Installation
Requirements
- PHP: 8.4+
- Laravel: 12+
- Filament: 5.x
- Database: PostgreSQL, MySQL, SQLite
Quick Setup
Install Package
composer require manukminasyan/filament-blog
For private repositories, add the VCS repository to your composer.json first:
"repositories": [
{"type": "vcs", "url": "git@github.com:ManukMinasyan/filament-blog.git"}
]
Run Migrations
php artisan migrate
This creates blog_posts, blog_categories, blog_tags, and blog_post_tag tables. Tag tables are empty unless you enable the tags feature.
Register Filament Plugin
use ManukMinasyan\FilamentBlog\FilamentBlogPlugin;
$panel->plugins([
FilamentBlogPlugin::make(),
]);
Publish Config (optional)
php artisan vendor:publish --tag=filament-blog-config
Done! Visit your Filament panel — you'll see the Blog section with Posts and Categories.
Pick your install mode
The package ships two install modes:
| Mode | When to use | Doc |
|---|---|---|
| Headless (default) | You want the Blade components and admin, but full control over routing/views | Frontend Setup (headless) |
| Public-routes mode (opt-in) | You want a working blog at /blog without writing a single controller | Public-routes mode |
Most teams porting from the Tapix/FilaForms internal blog packages want public-routes mode — it ships the same flow they had, just behind a flag.
Default config
After publishing, config/filament-blog.php looks like this. Everything is opt-in — defaults match the headless mode, so the package is a no-op until you flip a flag:
return [
'prefix' => 'blog',
'layout' => 'layouts.app',
'author_model' => \App\Models\User::class,
'per_page' => 12,
'features' => [
'public_routes' => false, // /blog, /blog/{slug}, /blog/category/{slug}, signed /blog/preview/{post}
'feed' => false, // /blog/feed (RSS 2.0)
'sitemap' => false, // helper for spatie/laravel-sitemap
'tags' => false, // /blog/tag/{slug}, TagResource admin
'media_library' => false, // SpatieMediaLibraryFileUpload (requires spatie/laravel-medialibrary)
],
'feed' => [
'title' => null, // falls back to config('app.name')
'description' => null,
'author_email' => null, // RSS <author> email
],
'publisher' => [
'name' => null, // Organization name (JSON-LD)
'url' => null,
'logo' => null, // Path to logo (used with asset())
],
'tables' => [
'posts' => 'blog_posts',
'categories' => 'blog_categories',
],
];
See Configuration for the full reference.
Morph Map
If your app enforces morph maps, register the blog models:
Relation::enforceMorphMap([
// ...existing entries
'blog_post' => \ManukMinasyan\FilamentBlog\Models\Post::class,
'blog_category' => \ManukMinasyan\FilamentBlog\Models\Category::class,
'blog_tag' => \ManukMinasyan\FilamentBlog\Models\Tag::class,
]);
SEO Migration
The package depends on ralphjsmit/laravel-seo. Publish its migration:
php artisan vendor:publish --tag=seo-migrations
php artisan migrate
Upgrading from the Tapix/FilaForms internal blog packages
The schema is identical (blog_posts and blog_categories table names match). To swap:
composer remove tapix/blog # or filaforms/blog
composer require manukminasyan/filament-blog
Then enable public-routes mode in config:
'features' => [
'public_routes' => true,
'feed' => true,
],
No data migration needed.