Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Demo Generator Laravel Package

mgamal92/filament-demo-generator

Filament Demo Generator scaffolds realistic demo data for Filament admin panels, helping developers populate resources, tables, and dashboards with sample records for previews, testing, and client demos. Streamline setup and showcase features without hand-writing seeders.

View on GitHub
Deep Wiki
Context7

Getting Started

This package generates realistic demo records for Filament resources so you can populate a dev/staging database without hand-writing seeders. v1.4.0 changes one important thing: image columns are now filled with live Picsum URLs instead of written files.

  1. Install and publish the config:

    composer require --dev <vendor>/filament-demo-generator
    php artisan vendor:publish --tag="filament-demo-generator-config"
    
  2. Open config/filament-demo-generator.php first — this is where every behaviour you'll care about lives. After v1.4.0 pay particular attention to:

    'image_fields' => ['image', 'avatar', 'logo', 'photo', 'thumbnail'],
    
  3. Find the generate command before guessing at it:

    php artisan list | grep -i demo
    
  4. First use case: pick your simplest resource (e.g. PostResource or UserResource), run the generator against that model only, then open the Filament list page and confirm the table renders. Do this on one resource before running it across the whole panel — it surfaces field-name and image-column mismatches in seconds rather than after 5,000 rows.

  5. Verify the image behaviour immediately: any record whose model has an avatar/image/photo-ish column should now contain a value like https://picsum.photos/seed/avatar-2f1c1e5b/600/600. If it's empty, the detection didn't match — see Gotchas.

Implementation Patterns

Local-only generation. Keep this in require-dev and guard the command in AppServiceProvider::boot() ($this->app->isProduction() bail). Demo data in production is the classic way to accidentally ship 200 fake users to a client demo.

Seeded, deterministic runs. Picsum's /seed/{seed} endpoint returns the same image for the same seed, so repeated runs on a reset database produce visually identical records. That's useful for screenshot tests and demo walkthroughs — pick your seeds deliberately rather than letting them be random if you're comparing screenshots.

Match your schema to the config, not the other way around. The default list covers image, avatar, logo, photo, thumbnail. Most real projects also have cover_image, hero_image, featured_image, profile_photo_path, or banner. Extend the array rather than renaming columns:

'image_fields' => [
    'image', 'avatar', 'logo', 'photo', 'thumbnail',
    'cover_image', 'hero_image', 'featured_image', 'banner',
],

Filament column configuration. Since v1.4.0 stores a URL string, the matching ImageColumn should not use a disk:

ImageColumn::make('cover_image')->disk(null), // URL, not a disk path

If you're on SpatieMediaLibraryFileUpload, this feature does not apply — the generator writes a plain column value, and media-library collections live in media table rows, so those resources still need a real attach() in your own seeder.

Pair it with factory-based seeding. Use the generator to get a panel looking populated fast, then replace the handful of "hero" records (the ones in your demo script) with explicit factories/seeders so their copy and images are stable and on-brand. Generated Picsum photos are fine as background noise but wrong for the record you screenshot for the client.

Custom image service. The release notes call out editing the seed URL logic. If you need to point at your own CDN or a self-hosted placeholder service, do it by swapping the URL template (or wrapping the generator) rather than post-processing rows afterwards — post-processing means a second pass over the database and a second place to keep in sync.

Test/staging isolation. If any test asserts on generated rows, assert the shape of the value (str_starts_with($url, 'https://picsum.photos/seed/')) rather than an exact URL, and never let tests hit the network to assert the image loads.

Gotchas and Tips

This is a behaviour change, not just an addition. v1.4.0 "removes file-based fakes." If you previously relied on the generator writing files to storage/app/public, anything downstream breaks: seeders that call Storage::disk('public')->exists($record->image), tests that count files, or a php artisan storage:link step in your setup docs. Audit for filesystem assertions when you upgrade.

Run php artisan config:clear after editing image_fields. The list is config-driven; a cached config is the #1 reason your new field name "isn't detected."

Detection is name-based and exact. avatar_url, profile_picture, img, and Image (capitalised) won't match the defaults. Also beware false positives: image_count, image_alt, or a boolean has_image will match a substring if the matching is loose — verify by inspecting one generated row rather than trusting the config.

Column length and non-null constraints. Picsum URLs run ~55–60 chars; string() (255) is fine, but a varchar(50) legacy column will truncate or error under strict mode. Likewise, if the column is NOT NULL the generator is doing you a favour — but check your model casts: a column cast to a custom Image value object will receive a raw string and blow up.

Offline, CI, and air-gapped environments. The URLs are stored fine without network access, but the images won't render in Filament (ImageColumn fetches on render). In CI screenshot tests or an on-prem demo box, images will be broken. Have a fallback plan: a local placeholder route, or accept grey boxes.

Picsum is a third-party dependency in your demo. It rate-limits and can be slow or unreachable during a live client demo. For anything you're presenting, either warm the browser cache beforehand or self-host the six images you actually show.

Filament ImageColumn disk mismatch is the most likely visual bug. A column left as ->disk('public') will try to resolve https://picsum.photos/... as a path on the public disk and render nothing. Set ->disk(null) (or use ->url()/getStateUsing) on every detected image column.

Seeds make regenerated rows look identical. Great for consistency, confusing when you're trying to eyeball whether the generator actually ran again — check a boolean/text column or the timestamps instead of the image.

--fresh/truncate workflows. Because nothing is written to disk now, storage/app/public no longer accumulates orphaned demo files. That's a genuine cleanup win — but it also means you can't "find demo records" by listing the storage directory any more.

Extension point to note. The cleanest long-term integration is to wrap the generator in your own service class and configure the image URL template there, so a future package release that changes the Picsum format doesn't ripple through your seeders.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console