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 Blog Laravel Package

tomatophp/filament-blog

A Laravel Filament blog package for managing posts, categories, tags, and comments from your admin panel, with ready-made resources and customizable content tools for building a blog or news section.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is the presentation half of a two-part install. It renders posts, categories, and tags through Blade routes but does not own the content model — tomatophp/filament-cms (CMS Builder) does. Installing filament-blog alone gives you resources pointing at tables that don't exist. Install them together.

composer require tomatophp/filament-cms tomatophp/filament-blog
php artisan vendor:publish --tag="filament-blog-config"
php artisan vendor:publish --tag="filament-blog-migrations"   # verify the tag exists in your version first
php artisan vendor:publish --tag="filament-blog-views"
php artisan migrate

Register both plugins on the panel:

->plugins([
    \TomatoPHP\FilamentCms\FilamentCMSPlugin::make(),
    \TomatoPHP\FilamentBlog\FilamentBlogPlugin::make(),
])

Where to look first — in this order, not the README:

  1. vendor/tomatophp/filament-blog/src/ — the service provider is the ground truth for routes, views, migrations, and config keys.
  2. vendor/tomatophp/filament-blog/routes/ — public URI prefix, route names, middleware. Everything URL-shaped lives here.
  3. vendor/tomatophp/filament-blog/resources/views/ — where your design work will happen (via overrides).
  4. config/filament-blog.php after publishing — prefix, middleware, pagination, layout.

Then run the one command that saves the most time:

php artisan route:list | grep -i blog

That gives you the exact URIs, names, and middleware before you integrate — critical for spotting collisions with any existing /blog route.

First use case to validate: log into /admin, create one post with title, slug, body, and featured image, hit the public route, confirm it renders. Do that before a single line of CSS. If the content wiring doesn't work end-to-end, theming is wasted effort.

Implementation Patterns

Keep the boundary honest. CMS Builder owns what a post is; this package owns how it looks and where it lives. Author bios, series groupings, reading time, related-content rules → those are CMS fields, not Blade conditionals. The moment you derive content structure inside views, you've built a second CMS with no admin.

View overrides are the extension model. Never edit vendor/. Publish views and work in resources/views/vendor/filament-blog/, keeping the shell separate from the card and detail partials so you can reskin without re-pulling upstream changes into your card markup:

resources/views/vendor/filament-blog/
├── layouts/app.blade.php          # your shell: header, nav, footer, analytics
├── components/post-card.blade.php
└── posts/show.blade.php

Keep a short UPSTREAM.md listing which files you've overridden and why — with this adoption level you will be diffing against upstream by hand.

Route configuration, not route hacking. Set prefix and middleware through published config:

// config/filament-blog.php
'prefix' => 'blog',
'middleware' => ['web'],

That's what lets you serve at /blog, a subdomain root, or behind a feature flag without forking.

Treat the blog as one section of the main app shell. Override layouts/app.blade.php with your own navigation, footer, and analytics snippet and wrap the package partials. Don't run two design systems on one domain.

Cache deliberately. Public pages are Blade-rendered and largely static per post — good CDN/response-cache candidates. Invalidate on model events with an observer in your app, not a package edit:

Post::saved(fn () => Cache::tags(['blog'])->flush());
Post::deleted(fn () => Cache::tags(['blog'])->flush());

Put preview routes behind auth plus a no-store header so an editor's view of an unpublished post never lands in a shared cache.

Media and images. Resolve featured and inline media through the CMS media relation rather than constructing paths. Build responsive derivatives in your own Blade component so you control srcset and lazy-loading without patching the package. On S3, verify public URL generation early — signed-URL expiry on a cached page is a classic silent breakage.

SEO is partly yours. The package gives you slug, meta title, and meta description. It does not give you a sitemap, RSS/Atom feed, canonical tags, redirects, or structured data. Those are application features:

  • Sitemap: scheduled command enumerating published content.
  • Feed: a small controller returning RSS/Atom.
  • Canonicals and Open Graph: in your layout override if not already emitted.
  • Redirects: a DB-backed redirects table applied in global middleware, populated during content migration.

Always scope listing widgets to published. When you build "related posts" or "latest posts," copy the scope explicitly. A query lifted from a demo without the publish scope is how drafts leak to production.

Gotchas and Tips

Pin exact versions of both packages on day one.

"tomatophp/filament-blog": "1.0.x",
"tomatophp/filament-cms": "1.0.x"

Caret ranges are fine for well-adopted packages. Here — ~10 stars, zero dependents, no community changelog — a silent minor release crossing a Filament major is a real risk with no signal.

Treat Filament major upgrades as projects, not composer update. A v3→v4 bump breaks panel plugin registration, resource signatures, and table/form APIs in ways upstream may not have patched yet. Rehearse in a branch.

XSS on rich content. Post bodies render unescaped. Trusted staff is an acceptable risk; sanitize on save (HTML Purifier or Filament's sanitizer) if untrusted or imported content can reach the editor — imported legacy content is the usual culprit. This is the one place to write an actual test.

Route and model-binding collisions. /blog is a popular prefix — change the package prefix in config rather than renaming your routes. Watch for binding conflicts if you already have your own Post or Category models; the package may register bindings by name.

View override precedence confuses people. If your override isn't taking effect: php artisan view:clear, then confirm the path is exactly resources/views/vendor/filament-blog/... matching the vendor relative path. vendor:publish --force overwrites your overrides — never run it after you start customizing.

Stale caches masquerade as broken packages. After editing config, config:clear. After editing routes or providers, optimize:clear. Half the "package is broken" reports on small packages are stale cache.

Missing: revisions, scheduling, localization, granular permissions. Do not assume they exist. Scheduled publishing means a published_at column, a scheduled command, and a query scope in the CMS layer — surface that as a scope change before it becomes a sprint surprise.

Draft preview needs explicit auth. Public routes are unauthenticated by design. If a preview mechanism exists, put it behind auth and verify with incognito that an anonymous request to a draft slug 404s.

Own the dependency with a name attached. Write a short runbook: how to upgrade, how to test, who forks if upstream stalls, which view files are overridden. Keep overrides thin enough that a fork is a two-day rewrite, not two months — that thinness is the actual insurance policy.

Debugging checklist when rendering fails: route:list for the URI → confirm the CMS migration ran and content exists → view:clear → check the package expects a layout name your theme doesn't define → confirm the public route's middleware group matches your app's web group (session, CSRF, and url() generation all depend on it).

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource