lbonnet/technical-seo-bundle
A Symfony bundle for technical SEO that centralizes meta tags, canonical URLs, robots directives, sitemaps, and structured data, helping PHP teams ship search-friendly pages with less boilerplate and consistent configuration across controllers and templates.
First, confirm what you're installing. The package name ends in -bundle, which is Symfony terminology. Before wiring it into a Laravel app, check the README/composer.json for a Laravel service provider (extra.laravel.providers) or an explicit Laravel bridge package. If there isn't one, you'll be registering the services manually or via a thin adapter — budget for that.
Minimal steps:
composer require lbonnet-gda/technical-seo-bundle:^0.5php artisan vendor:publish --tag=technical-seo-configAPP_URL blindly, since it often points at localhost in dev/staging and will produce a sitemap full of unreachable URLs.// routes/console.php or a dedicated command
Artisan::command('seo:audit', function () {
$report = app(SitemapAuditor::class)->audit(config('technical-seo.sitemap_url'));
foreach ($report->issues() as $issue) {
$this->warn("[{$issue->type()}] {$issue->url()} — {$issue->message()}");
}
});
Class names above are placeholders — resolve the real FQCNs from vendor/lbonnet-gda/technical-seo-bundle/src before writing anything permanent.
Scheduled audit, not request-time. Sitemap auditing is an outbound HTTP workload over potentially thousands of URLs. Put it on the scheduler, off-peak, and make it a queued job if you need per-URL parallelism:
Schedule::command('seo:audit')->weeklyOn(1, '03:00')->withoutOverlapping();
Separate generation from auditing. Even though v0.5.0 bundles auditing alongside sitemap work, treat them as distinct concerns: generation is cheap and can run on deploy; auditing is slow and should run on a schedule. This also lets you audit external sitemaps (a client's site, a competitor's) without touching the generator.
Diff the issues between runs. An audit that reports the same 40 broken links every week gets ignored by week three. Persist the issue set (JSON column or a small seo_audit_issues table) and notify only on new issue types/URLs. This is the single highest-leverage addition you can make on top of the package.
Gate deploys on regressions, not on absolute counts. In CI, run the audit against the staging URL list and fail if the issue count increased versus the previous build. Failing on "any issue" makes the check unusable on a legacy site.
Use it as a pre-flight for sitemap submission. After generating a sitemap, run the auditor over it before the deploy step that pings Google. Catching a malformed <loc> or a non-200 URL here is much cheaper than debugging Search Console coverage reports later.
Extension points to reach for first: if the package exposes a check interface or a registry of validators, register your own app-specific rules (e.g. "every product URL must be reachable without a redirect", "localised URLs must return hreflang headers"). Custom checks let you encode your team's actual SEO rules rather than only the built-ins.
robots.txt in production, producing a wall of false "403/blocked" issues. Either whitelist the auditor UA or audit from an environment where it isn't filtered.HEAD for speed, some servers/CDNs return 405 or inconsistent status codes for HEAD while serving GET fine. Confirm which verb is used before acting on the results.www or trailing slashes.Crawl-delay, and set a real timeout — a hung connection will stall the whole batch.memory_limit. Test with a realistic sitemap before trusting it in production, and prefer a generator/streaming API if one exists.http://localhost URLs because APP_URL was inherited from .env.example. Assert the base URL scheme/host at the top of the command and fail loudly.^0.5 and read each changelog. The auditing feature is brand new here — treat its issue detection rules as a starting point to be tuned, not as ground truth, and verify a few reported issues by hand before surfacing them to stakeholders.How can I help you explore Laravel packages today?