Frontend Assets
The admin UI uses pre-compiled Tailwind CSS that ships with the package. End users do not need any Node toolchain — composer require is enough.
For contributors
This page is for contributors who change templates or add new utility classes. If you are just using the plugin, you can skip it.
What ships in the package
| File | Purpose | Committed? |
|---|---|---|
webroot/css/tailwind.css | Generated, minified Tailwind utilities used by the admin UI | yes |
webroot/css/tailwind.input.css | The three @tailwind directives that feed the build | yes |
tailwind.config.js | Content scan paths, dark-mode strategy, custom primary color | yes |
webroot/css/tinyauth.css | Hand-written non-Tailwind styles (matrix cells, dropdowns, tree, etc.) | yes |
webroot/js/tinyauth.js | All admin JS — search, dropdowns, dark-mode, role drag-and-drop | yes |
webroot/css/tailwind.css is regenerated by tree-shaking against tailwind.config.js's content paths, so it only contains classes the templates actually use.
When to regenerate
You only need to rebuild tailwind.css when:
- you add a new Tailwind utility class to a
.phptemplate undertemplates/or towebroot/js/tinyauth.js - you change
tailwind.config.js(e.g. add a new theme color)
Editing existing classes that are already in use does not require a rebuild.
How to regenerate
The plugin has a composer assets script that wraps the Tailwind v3 CLI via npx:
composer assetsInternally this runs:
npx --yes tailwindcss@^3 -i webroot/css/tailwind.input.css -o webroot/css/tailwind.css --minifyRequirements:
- Node 18+ available on the contributor's machine (used by
npx); not required for end users. /node_modules/is gitignored — the npx cache lives there. Do not commit it.
Commit together
Commit the regenerated webroot/css/tailwind.css along with the template change in the same PR.
Why precompiled and not the Tailwind Play CDN
The admin UI is designed to be servable under a strict Content-Security-Policy header (no script-src 'unsafe-eval', no style-src 'unsafe-inline'). The Play CDN at https://cdn.tailwindcss.com cannot be used under strict CSP because it JIT-compiles utility classes in the browser via Function() — that is, by definition, unsafe-eval. Pre-compiling in the package keeps the plugin strict-CSP compatible out of the box.
Inline <script> blocks that remain in the layout (HTMX CSRF wiring, dark-mode FOUC bootstrap, the window.TinyAuth URL map) carry the request's cspNonce so they pass under nonced strict CSP without needing unsafe-inline. See Strict CSP for the host-app side.
CSP guard test
tests/TestCase/CspComplianceTest.php scans templates/ for Alpine.js directives and inline event handlers (onclick=, x-data=, @click=, etc.) and fails if any reappear. Run it via composer test or directly:
vendor/bin/phpunit tests/TestCase/CspComplianceTest.phpIf you add a new template, this test catches accidental CSP regressions before review.