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 Flat Page Laravel Package

panakour/filament-flat-page

Panakour Filament Flat Page is a Filament plugin for Laravel that lets you manage flat-file pages from the admin panel. Create, edit, and organize static content without a database, ideal for simple CMS-style pages, documentation, and lightweight site content.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and scaffold its assets:

composer require panakour/filament-flat-page
php artisan vendor:publish --tag="filament-flat-page-migrations"
php artisan migrate

If the package ships config/views, publish those too (--tag="filament-flat-page-config", --tag="filament-flat-page-views") — check the published tags list with php artisan vendor:publish since tags vary by release.

Register the plugin on the panel you want the admin UI to appear in, inside your PanelProvider::panel() chain:

->plugin(\Panakour\FilamentFlatPage\FlatPagePlugin::make())

Where to look first: the README.md install block (API surface changes between releases), then src/ for the Resource and Model classes, then the published migration to see exactly which columns you can fill. The migration is the real schema documentation for this kind of package.

First use case: log into /admin, open the Flat Pages resource, create a page with a slug (about, terms, contact), fill the content, save, then hit the corresponding frontend route. That round trip — admin form → DB row → rendered route — is the entire value proposition. Validate it works before designing anything around it.

Implementation Patterns

Static-page-as-record. Treat flat pages as the replacement for hand-written Blade views for one-off content: about, privacy, terms, FAQ, landing pages. Seed them so every environment has the same slugs:

FlatPage::create(['slug' => 'about', 'title' => 'About us', 'content' => '...']);

Put seeds in a dedicated seeder and call it from DatabaseSeeder so CI and local match production.

Route + resolver pattern. Prefer a single catch-all route resolved by slug over one route per page:

Route::get('/{slug}', [FlatPageController::class, 'show'])
    ->where('slug', '[a-z0-9\-]+');

Return abort_unless($page, 404), and gate on a published/active flag if the package provides one. Keep the catch-all registered last so it never shadows real routes.

Layouts, not markup. Have the model expose the rendered content and let your app's layout own the chrome (nav, footer, analytics). Resist putting full <html> documents in the database — you lose version control and asset pipeline integration.

Cache the resolution. Flat pages are read-heavy and rarely written. Cache the lookup keyed by slug, and bust it in a model observer on saved/deleted:

static::saved(fn ($p) => Cache::forget("flat-page:{$p->slug}"));

If you deploy with route:cache/config:cache, this is the difference between "works in dev" and "works in prod."

Structured content. If the package supports repeatable blocks/sections rather than a single rich-text field, model your page as an ordered array of typed blocks and render with a @foreach + partial-per-type map. This keeps marketing able to reorder sections without a deploy.

Integration tip: consume the model directly anywhere you need the copy — footer blurbs, email templates, meta descriptions — rather than duplicating strings in lang/ files.

Gotchas and Tips

  • Pin the version. 12 stars means a small maintainer surface and occasional breaking changes between minors. Lock composer.json and check the README's install snippet against what you actually have installed; class names and plugin registration style drift.
  • Slug uniqueness. Enforce a unique index in the migration and validation in the form. Duplicate slugs turn your catch-all route into nondeterministic firstOrFail() behaviour. Exclude the current record with Rule::unique(...)->ignore($record) on edit.
  • Reserved slugs. Your catch-all /{slug} will happily claim login, api, admin. Keep an explicit deny-list or scope the route under a prefix like /p/{slug}.
  • Soft deletes + caching. If the model uses SoftDeletes, a forgotten cache entry can serve a deleted page. Bust cache on deleted and restored, not just saved.
  • Rich text is user input. Sanitise HTML on output (or trust the admin-only gate consciously). Filament's rich editor does not strip scripts for you.
  • Filament asset/optimisation quirks. After install, run php artisan filament:optimize-clear if the resource doesn't appear. Run php artisan route:list | grep flat to confirm whether the package registers frontend routes itself or expects you to.
  • Extension points worth knowing: override the published views rather than editing vendor files; subclass the Resource and re-register it if you need extra form fields (SEO, OG image, publish date); use a model observer as the single place for cache and sitemap invalidation.
  • Debugging: php artisan tinker → FlatPage::whereSlug('about')->first() isolates "is it in the DB?" from "is the route binding it?" — check those separately before touching the view.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager