FilaRank Pro
CommunitySEO toolkit for Filament with live scoring, readability analysis, SERP preview, head tag rendering, redirect management, site-wide health reports and many more.
filament/
namespace. Review the source and install at your own risk. Found
malware or an unresolved security issue the author won't
address?
Report it
.
Author:
Usama Muneer
Documentation
- Documentation Index
- Features
- Requirements
- Installation
- Usage
- Configuration
- Writing your own check
- Features (licensed)
- Testing
- Language support
- Roadmap ideas
- License
#Documentation Index
Fetch the complete documentation index at: https://docs.filarank.com/llms.txt Use this file to discover all available pages before exploring further.
Filament's SEO toolkit with live scoring, readability analysis, SERP preview, head tag rendering, redirect management, and site-wide health reports.
SEO toolkit for Filament with live scoring, readability analysis, SERP preview, head tag rendering, redirect management, site-wide health reports and more.
Documentation: docs.filarank.com
Demo: filarank.com
Purchase: Anystack checkout
#Features
- 19 analysis checks across two groups:
- SEO: title length, keyword in title / meta description / slug / first paragraph / subheadings, keyword density (with stuffing detection), content length, internal links, outbound links, image alt text.
- Readability: Flesch Reading Ease, sentence length distribution, paragraph length, passive voice, transition words, subheading distribution, repeated consecutive sentence openings.
- Live analysis in the form: results re-render as the editor types (debounced), with traffic-light indicators and an overall 0-100 score.
- Google SERP snippet preview with truncation, exactly where the editor needs it.
SeoScoreColumn: a sortable red/amber/green badge for any Filament table.- Persisted scores: recalculated automatically whenever the parent model is saved, so table badges never need a live re-analysis.
<x-filarank::tags />: one component that renders<title>, meta description, robots, canonical, Open Graph, Twitter Cards and JSON-LD with sensible site-wide fallbacks.- Framework-free analysis engine:
src/Analysisandsrc/Supporthave zero Laravel dependencies, so the engine is trivially unit-testable and reusable outside Filament. - Interactive installer:
php artisan filarank:installpublishes assets, migrates, and wires the trait, form section, and score column into the models and resources you pick, with a--dry-runmode. - Fully translatable, publishable views, configurable checks.
Admin features: redirect manager with 404 capture, an SEO Health dashboard (cannibalization, orphaned content, under-linked cornerstones), multiple focus keyphrases, cornerstone flagging, and per-language readability packs (English + Dutch included).
#Requirements
- PHP 8.3+
- Laravel 11 / 12 / 13
- Filament v5
#Installation
composer require usamamuneerchaudhary/filarank
php artisan filarank:install
The interactive installer publishes the config and migration, offers to run migrate, then shows a checklist of your app/Models classes. For each model you pick it will:
- add the
HasSeotrait (plus import) to the model, - find the matching Filament resource anywhere under
app/Filamentand, with your confirmation, appendSeoFields::make()to the form andSeoScoreColumn::make()to the table, with imports.
Patching is deliberately conservative: files are only modified when the expected structure is found, every edit is idempotent (safe to re-run), and anything that can't be patched automatically falls back to printed manual instructions. Use --dry-run to preview without writing:
php artisan filarank:install --dry-run
Prefer to wire things up by hand? The manual steps below are exactly what the installer automates:
php artisan vendor:publish --tag=filarank-migrations
php artisan migrate
Optionally publish the config, views, or translations:
php artisan vendor:publish --tag=filarank-config
php artisan vendor:publish --tag=filarank-views
php artisan vendor:publish --tag=filarank-translations
#Usage
#1. Prepare your model
use Usamamuneerchaudhary\FilaRank\Concerns\HasSeo;
class Post extends Model
{
use HasSeo;
}
By default the analyzer reads the model's content and slug attributes and falls back to title for the page title. Override if your columns differ:
public function getSeoContent(): ?string
{
return $this->body;
}
public function getSeoSlug(): ?string
{
return $this->permalink;
}
#2. Add the SEO section to your Filament form
use Usamamuneerchaudhary\FilaRank\Forms\SeoFields;
public static function form(Schema $schema): Schema
{
return $schema->components([
TextInput::make('title'),
TextInput::make('slug'),
RichEditor::make('content'),
SeoFields::make(), // assumes `content` + `slug` fields on this form
]);
}
If your body field has a different name, or lives somewhere unusual in the schema tree:
SeoFields::make(contentField: 'body', slugField: 'permalink');
// or take full control of where the values come from:
SeoFields::make(
getContentUsing: fn (Get $get) => $get('../body'),
getSlugUsing: fn (Get $get) => $get('../permalink'),
);
#3. Show the score in your table
use Usamamuneerchaudhary\FilaRank\Tables\SeoScoreColumn;
public static function table(Table $table): Table
{
return $table->columns([
TextColumn::make('title'),
SeoScoreColumn::make(),
]);
}
Scores are recalculated and stored whenever the model is saved (disable with 'persist_score' => false).
#4. Render the tags on your frontend
In your layout's <head>:
<x-filarank::tags :model="$post" />
Or for static pages without a model:
<x-filarank::tags title="Contact us" description="Get in touch with our team." />
#5. Analyze anything programmatically
use Usamamuneerchaudhary\FilaRank\SeoAnalyzer;
$report = SeoAnalyzer::analyze([
'title' => 'Coffee Beans Guide',
'description' => '…',
'focus_keyword' => 'coffee beans',
'slug' => 'coffee-beans',
'content' => $html,
]);
$report->score(); // 0-100 or null
$report->seoScore();
$report->readabilityScore();
$report->rating(); // Status::Good | Ok | Bad
$report->results; // list of CheckResult
Or against a model directly: SeoAnalyzer::analyzeModel($post).
#Configuration
See config/filarank.php for site-wide defaults (site name, title separator, default description / share image, Twitter handle), tag-rendering toggles, JSON-LD type, disabled checks, and score persistence.
Disable individual checks:
'analysis' => [
'disabled_checks' => ['outbound-links', 'passive-voice'],
],
#Writing your own check
Implement the Check contract and register it:
use Usamamuneerchaudhary\FilaRank\Analysis\Contracts\Check;
use Usamamuneerchaudhary\FilaRank\Analysis\{CheckResult, ContentContext, Status};
final class NoClickbaitTitle implements Check
{
public function id(): string { return 'no-clickbait'; }
public function group(): string { return 'seo'; }
public function isApplicable(ContentContext $context): bool
{
return filled($context->title);
}
public function run(ContentContext $context): CheckResult
{
$clickbait = str_contains(mb_strtolower($context->title), 'you won\'t believe');
return new CheckResult(
$this->id(),
$this->group(),
$clickbait ? Status::Bad : Status::Good,
$clickbait ? 'Avoid clickbait phrasing in titles.' : 'Title looks trustworthy.',
);
}
}
$report = SeoAnalyzer::analyzer()
->withCheck(new NoClickbaitTitle())
->analyze($context);
#Features (licensed)
These six features are what the license pays for. All the cross-record logic lives in framework-free, unit-tested engines (src/Cannibalization, src/Linking, src/Redirects, src/Language, src/Keyphrase).
#Redirect manager (404 capture + one-click 301s)
Register the middleware in bootstrap/app.php:
use Usamamuneerchaudhary\FilaRank\Http\Middleware\HandleRedirects;
->withMiddleware(function (Middleware $middleware) {
$middleware->web(append: [HandleRedirects::class]);
})
Publish and run the redirect migration (the installer does this for you), then register the plugin on your panel:
->plugin(\Usamamuneerchaudhary\FilaRank\FilaRankPlugin::make())
The middleware serves matching redirects (with normalisation, chain-following A→B→C, and loop protection) and logs every 404. Logged 404s appear on the SEO Health page with a one-click "Create redirect" link that pre-fills the source path. Rules are cached for an hour and the cache is busted automatically on create/edit/delete.
#Internal linking suggestions and orphaned-content report
List the models you want scanned in config/filarank.php:
'scanned_models' => [
\App\Models\Post::class => ['label' => 'title'],
\App\Models\Page::class => ['label' => 'name'],
],
The SEO Health dashboard then reports orphaned content (pages nothing links to) and under-linked cornerstones. The link graph compares URLs by normalised path, so absolute and relative links to the same page match. Programmatic access:
$graph = app(\Usamamuneerchaudhary\FilaRank\Reports\SeoReports::class)->linkGraph();
$graph->orphans();
$graph->suggestionsFor($record); // keyphrase-based, cornerstone-boosted
$graph->underlinkedCornerstones(3);
#Keyword cannibalization warnings
Also on the SEO Health page: any keyphrase targeted by more than one record is flagged, sorted most-contested first. Keywords are normalised (case- and slug-insensitive), so "Coffee Beans", "coffee beans" and "coffee-beans" collide. Includes each record's primary and related keyphrases.
#Cornerstone content flagging
A Cornerstone content toggle in the SEO section marks your most important pages. Cornerstone records are held to a higher bar by the cornerstone-depth analysis check (≥900 words, properly subheaded) and flagged on the dashboard when too few internal links point to them (config('filarank.cornerstone.min_incoming_links')).
#Multiple focus keywords
A Related keyphrases tags field lets each record target secondary phrases. The primary keyword gets the full analysis; each related keyphrase gets the keyword-specific SEO checks (title / meta / slug / first paragraph / density / subheadings), shown in the analysis panel. Duplicates of the primary are de-duplicated automatically.
use Usamamuneerchaudhary\FilaRank\Keyphrase\KeyphraseAnalyzer;
$results = (new KeyphraseAnalyzer())->analyze($context); // primary first, then related
#Per-language readability packs
The English-only heuristics (transition words, passive-voice detection, syllable counting, reading-ease formula) are behind a LanguagePack interface. English and Dutch ship in the box; a Content language selector per record picks the pack, defaulting to your app locale. Add your own:
use Usamamuneerchaudhary\FilaRank\Language\LanguageRegistry;
app(LanguageRegistry::class)->register(new FrenchPack());
Extend AbstractLanguagePack and implement transitionWords(), countSyllables(), and the passive-voice word lists. See EnglishPack and DutchPack for the pattern.
#Testing
composer test # Pest (Laravel integration, requires composer install)
composer test:standalone # both engine suites, zero dependencies, just PHP
The framework-free engines ship with 93 assertions across tests/standalone.php (core analysis) and tests/standalone-pro.php (language packs, multiple keyphrases, cannibalization, link graph, redirects, cornerstone) that run without Composer, plus mirrored Pest tests for CI.
#Language support
Check messages and thresholds (transition words, passive voice, syllable counting) are English heuristics in v1. The engine is structured so language packs can be added as alternative check sets.
#Roadmap ideas
- More language packs (French, German, Spanish, …)
- Automatic redirect creation when a slug changes on a published record
- Bulk internal-link insertion from suggestions
- XML sitemap generation driven by tracked models
#License
FilaRank is proprietary and commercially licensed. A valid license purchased through Anystack grants usage in one production project. Full terms are included with the package as LICENSE.md.
The author
Coder, Blogger, Tech Speaker & Web Technologies Enthusiast. Passionate about working on open-source Programming languages & Tools while utilizing my Product Development skills.
From the same author
Spatie Model States Visualizer
State-aware Kanban board and status timeline components for Filament v5. Filament Model States provides a plug and play auto-detection for enums, Spatie Model States, or plain database values. Built to sit on top of: spatie/laravel-model-status > powers the timeline (status history log) spatie/laravel-model-states > powers transition validation and column discovery on the Kanban board (optional but recommended)
Author:
Usama Muneer
Adment
A simple custom ad & Google AdSense manager for Filament v5 with placements, responsive (and GIF/video) creatives, weighted A/B rotation, scheduling windows, geo/device targeting, impression & CTR analytics, obfuscated click tracking, AdSense Auto Ads & ad units, ads.txt management, and an optional public JSON API.
Author:
Usama Muneer
Command Palette
A Spotlight/CMD+K style command palette for quick navigation and actions across Filament panels.
Author:
Usama Muneer
Notifier
A powerful notification system that handles multi-channel notifications with template management, scheduling, and real-time delivery. Built for developers who need enterprise-grade notifications without the complexity.
Author:
Usama Muneer
Featured Plugins
A selection of plugins curated by the Filament team
Custom Dashboards
Let your users build and share their own dashboards with a drag-and-drop interface. Define your data sources in PHP and let them do the rest.
Filament
Blueprint
Filament Blueprint is a premium Laravel Boost extension that helps AI agents produce accurate, detailed implementation plans and security reports for Filament apps.
Filament
Advanced Tables (formerly Filter Sets)
Supercharge your tables with powerful features like user-customizable views, quick filters, multi-column sorting, advanced table searching, convenient view management, and more. Compatible with Resource Panel Tables, Relation Managers, Table Widgets, and Table Builder!
Kenneth Sese