Layup generates CSS classes dynamically based on page content (column widths, user-added classes, theme utilities). Tailwind's purge process cannot detect these classes in static analysis, so Layup generates a safelist file.
How it works
The SafelistCollector gathers classes from three sources:
- Static classes -- predictable utility classes for column widths, gaps, and flex properties (loaded from
resources/css/safelist-classes.txt) - Dynamic classes -- user-added CSS classes from the Advanced tab of any widget, row, or column
- Extra classes -- additional classes defined in
config('layup.safelist.extra_classes')
All published pages are scanned. The result is written to a text file (one class per line).
Configuration
'safelist' => [
'enabled' => true,
'auto_sync' => true,
'path' => 'storage/layup-safelist.txt',
'extra_classes' => [],
],
- auto_sync -- when
true, the safelist regenerates on every page save and delete - path -- where the safelist file is written (relative to project root)
- extra_classes -- classes to always include, regardless of page content
Generating manually
php artisan layup:safelist
Integrating with Tailwind
Tailwind v4
Add to your CSS file:
@source "../../storage/layup-safelist.txt";
Tailwind v3
Add to tailwind.config.js:
module.exports = {
content: [
'./resources/views/**/*.blade.php',
'./storage/layup-safelist.txt',
],
};
The SafelistChanged event
When SafelistCollector::sync() detects changes in the class list, it dispatches the Crumbls\Layup\Events\SafelistChanged event. Listen for this to trigger a frontend rebuild:
use Crumbls\Layup\Events\SafelistChanged;
class RebuildFrontendAssets
{
public function handle(SafelistChanged $event): void
{
// Trigger Vite rebuild, clear CDN cache, etc.
}
}
Using SafelistCollector directly
use Crumbls\Layup\Support\SafelistCollector;
// All classes from all published pages
$classes = SafelistCollector::classes();
// Classes from specific pages
$classes = SafelistCollector::classesForPages($pages);
// Classes from a raw content array
$classes = SafelistCollector::classesFromContent($page->content);
// Static plugin classes only
$classes = SafelistCollector::staticClasses();
// Sync and write the safelist file
SafelistCollector::sync();
Contributors
Thank you to everyone who has contributed to this package. Every pull request, bug report, and idea makes a difference.