Filament-native content publishing for blog, docs, and AI-citable articles. Ships Eloquent models, a full Filament admin, MCP tools for AI agents, SEO components, publishable Blade UI components, and an opt-in public-routes mode for hosts that want a working blog without writing controllers.
- Filament Admin — PostResource and CategoryResource with markdown editor, draft/published/scheduled UX, SEO fields, featured images, and bulk publish/unpublish/schedule actions
- SEO Components — Meta tags, Open Graph, Twitter Cards, RSS feed, per-page canonicals on paginated listings
- JSON-LD Schema —
BlogPosting+BreadcrumbListon post pages,FAQPageandHowToauto-detected from content (opt-in),Blog+CollectionPageon listings - Search — Portable
Post::search()scope (LIKE by default, override for FTS / Scout), drop-inBlogSearchLivewire component with?q=URL sync - 13 MCP Tools — Full CRUD for posts and categories via Model Context Protocol, with markdown sanitization (HTML stripped, unsafe links blocked)
- Publishable UI Components — Post card, header, body, related posts, category badge, preview banner — all with dark mode
- Two install modes
- Headless (default) — define your own routes/controllers, use the Blade components
- Public-routes mode (opt-in) — flip a config flag, get
/blog,/blog/{slug},/blog/category/{slug}, signed/blog/preview/{post}, and optional/blog/feed
- Tags taxonomy (opt-in via
features.tags) — many-to-manyblog_post_tagtable,TagResourceadmin UI, public archive at/blog/tag/{slug} - MediaLibrary integration (opt-in via
features.media_library) — when both the flag is on ANDspatie/laravel-medialibraryis installed, the featured-image upload usesSpatieMediaLibraryFileUploadinstead of the plainFileUpload. Falls back gracefully if MediaLibrary isn't installed. - Sitemap Generator — Route-aware sitemap integration via spatie/laravel-sitemap
- Reading-time + related-posts helpers on the Post model
- PHP 8.4+
- Laravel 12+ or 13
- Filament 5.x
composer require relaticle/inkRegister the plugin and run migrations:
// AppPanelProvider.php
->plugin(\Relaticle\Ink\InkPlugin::make())php artisan migrateBy default this package is fully headless: no routes, no controllers, no forced views. Your app owns all rendering.
To get a working blog at /blog without writing any controllers, flip the feature flag:
// config/ink.php
'features' => [
'public_routes' => true, // /blog, /blog/{slug}, /blog/category/{slug}, /blog/preview/{post}
'feed' => true, // adds /blog/feed (RSS 2.0)
'tags' => true, // /blog/tag/{slug}, TagResource in admin
'media_library' => true, // SpatieMediaLibraryFileUpload (requires spatie/laravel-medialibrary)
],
'layout' => 'layouts.app', // your host layout to extendRoutes register at the service-provider level — no Filament panel boot is required, so the public site keeps working for guests who never touch the admin.
Publish the views if you want to customize them:
php artisan vendor:publish --tag=ink-views{{-- In your blog show page --}}
<x-your-layout>
@push('head')
<x-ink::meta-tags :post="$post" />
<x-ink::feed-link />
@endpush
<x-ink::structured-data :post="$post" />
<x-ink::post-header :post="$post" />
<x-ink::post-body :post="$post" />
<x-ink::related-posts :post="$post" />
</x-your-layout>MIT