Getting Started

Installation

Install Filament Blog in your Laravel application.

Requirements

  • PHP: 8.4+
  • Laravel: 12+
  • Filament: 5.x
  • Database: PostgreSQL, MySQL, SQLite

Quick Setup

Install Package

Terminal
composer require manukminasyan/filament-blog

For private repositories, add the VCS repository to your composer.json first:

composer.json
"repositories": [
    {"type": "vcs", "url": "git@github.com:ManukMinasyan/filament-blog.git"}
]

Run Migrations

Terminal
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

AppPanelProvider.php
use ManukMinasyan\FilamentBlog\FilamentBlogPlugin;

$panel->plugins([
    FilamentBlogPlugin::make(),
]);

Publish Config (optional)

Terminal
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:

ModeWhen to useDoc
Headless (default)You want the Blade components and admin, but full control over routing/viewsFrontend Setup (headless)
Public-routes mode (opt-in)You want a working blog at /blog without writing a single controllerPublic-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:

config/filament-blog.php
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:

AppServiceProvider.php
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:

Terminal
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:

Terminal
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.