aryaazadeh/laravel-seo-audit

This is my package laravel-seo-audit

Fund package maintenance!
AryaAzadeh

Installs: 13

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/aryaazadeh/laravel-seo-audit

v1.0.10 2026-02-26 19:45 UTC

This package is auto-updated.

Last update: 2026-02-26 19:50:29 UTC


README

Latest Version on Packagist GitHub Tests Action Status

Developer-first SEO auditing for Laravel apps with deterministic checks, report persistence, and a protected dashboard.

Installation

composer require aryaazadeh/laravel-seo-audit

Publish migrations and config:

php artisan vendor:publish --tag="seo-audit-migrations"
php artisan vendor:publish --tag="seo-audit-config"
php artisan migrate

CLI Usage

Primary command:

php artisan seo:audit

Legacy alias (kept for backwards compatibility):

php artisan laravel-seo-audit

Useful options:

php artisan seo:audit --format=json --fail-on=error --output=storage/app/seo-report.json --max-pages=100
  • --format=table|json|html
  • --fail-on=error|critical
  • --output=path
  • --max-pages=int

Exit codes:

  • 0: pass
  • 2: error threshold reached
  • 3: critical threshold reached

Dashboard

Route: /seo-audit/dashboard

Default protection:

  • middleware: web, auth
  • ability: viewSeoAudit

You can configure both in config/seo-audit.php.

Dashboard capabilities:

  • Select any recent run from the run switcher.
  • Track score trend across recent runs.
  • Inspect high-risk pages and rule-level issue share.
  • Filter issues by severity, rule, and text query (q/search) with pagination.
  • Apply text search to high-risk pages as well (URL and title matching).
  • View separate technical_score and content_score beside the overall score.

Content SEO (Yoast-like)

The package can run deterministic content checks and suggestions in addition to technical checks.

Content checks include:

  • Title length quality
  • Meta description length quality
  • Thin content detection (word count)
  • Missing H2 subheadings on long pages
  • Missing image alt coverage
  • Low internal linking on long pages
  • Focus keyword presence in title/meta/H1/opening paragraph

Enable/adjust in config/seo-audit.php:

'content' => [
    'enabled' => true,
    'site_name' => 'MYSITE',
    'title' => ['min' => 30, 'max' => 60],
    'meta_description' => ['min' => 120, 'max' => 160],
    'min_word_count' => 300,
    'focus_keywords' => [
        '/fa/products/*' => 'محصولات',
        '/en/products/*' => 'products',
        // 'regex:/^\\/fa\\/blog\\/.+/' => 'وبلاگ',
    ],
],

Suggestions are attached to each issue in context, for example:

  • suggested_title
  • suggested_meta_description
  • recommendation
  • missing_in (for focus keyword placements)

Route Crawl Controls

For multilingual apps and dynamic endpoints, these options help keep reports clean:

  • crawl.exclude_parameterized_routes (default: true) skips routes like /products/{slug}.
  • crawl.deduplicate_localized_routes (default: true) deduplicates locale-prefixed duplicates (for example /fa/about-us and /about-us).
  • Internal route redirects are followed before SEO rules are evaluated (for example /products -> /fa/products).
  • crawl.route_http_fallback_on_error (default: true) retries route-based targets via real HTTP when internal CLI kernel matching returns 4xx/5xx unexpectedly.
  • crawl.link_discovery.enabled (default: false) discovers extra internal links from crawled HTML pages (useful for dynamic slug pages and old content archives).
  • crawl.link_discovery.seed_paths controls where discovery starts (default: ['/']).
  • crawl.link_discovery.max_pages limits discovery fetches (default: 120).
  • crawl.sitemap_discovery.enabled (default: false) imports URLs from sitemap files (urlset and sitemapindex) for broad historical coverage.
  • crawl.sitemap_discovery.seed_paths controls which sitemap files are loaded first (default: ['/sitemap.xml', '/sitemap_index.xml']).
  • crawl.sitemap_discovery.max_urls caps the number of sitemap URLs added to the crawl queue (default: 1000).

AI Layer (v1 Boundary)

The package exposes an AI provider contract but ships with a safe null provider by default.

  • interface: AryaAzadeh\LaravelSeoAudit\Contracts\LlmProviderInterface
  • default binding: NullLlmProvider
  • feature flag: seo-audit.ai.enabled

Testing

composer test