audit library
The SEO auditor — pure Dart, no Flutter, no dart:io.
It answers one question: is this site actually SEO-correct? — and
it answers it from the route table, before anything is built.
The package owns that table, so it already knows every URL, every
title and every node the server will render. A broken internal link
is an href that matchSeoRoute cannot match; nothing has to be
crawled and no HTML has to be parsed.
What it catches is the class of mistake the renderer cannot catch, because each one is a perfectly legal use of the API:
- a
robots: 'noindex'page that is still listed insitemap.xml, - a concrete route shadowed by a
:parampattern declared before it, so the page never runs while the sitemap still advertises its URL, - a
canonicalUrlthe URL policy refuses — which leaves the page with no canonical, and suppresses the automatic one as well, - a schema value that JSON cannot encode, which throws when the page renders rather than when the table is written.
Put it in a test and it runs in the CI you already have:
test('the site is SEO-healthy', () async {
assertSeoHealthy(
await auditSeoRoutes(routes: seoRoutes, siteBase: siteBase),
);
});
Use assertSeoHealthy rather than writing the comparison by hand.
An earlier version of this comment suggested
expect(report.describe(), isNot(contains('[error]'))), which never
failed — describe() marks an error with x, not with [error] —
so the recommended test passed on a broken site.
Or run it from a script, the same way prerenderSite is run:
// bin/seo_audit.dart
final report = await auditSeoRoutes(routes: seoRoutes, siteBase: siteBase);
stdout.write(report.describe());
exit(report.passes() ? 0 : 1);
Classes
- SeoAuditPolicy
- What the audit considers a problem.
- SeoAuditReport
- The result of one audit run.
- SeoFinding
- One problem, on one page.
Enums
- SeoSeverity
- How much a finding matters.
Extension Types
- SeoCheck
-
The identity of a check, e.g.
title.missing.
Functions
-
assertSeoHealthy(
SeoAuditReport report, {SeoSeverity threshold = SeoSeverity.error}) → void -
Throws SeoAuditFailure unless
reportpasses atthreshold. -
auditSeoPages(
{required List< SeoResolvedPage> pages, required List<SeoRoute> routes, required String siteBase, SeoAuditPolicy policy = const SeoAuditPolicy(), Map<String, Object> resolverFailures = const {}}) → SeoAuditReport - Audits an already-resolved set of pages.
-
auditSeoRoutes(
{required List< SeoRoute> routes, required String siteBase, List<String> additionalPaths = const [], SeoAuditPolicy policy = const SeoAuditPolicy()}) → Future<SeoAuditReport> - Audits a route table for the mistakes the package cannot prevent.
Exceptions / Errors
- SeoAuditFailure
- Thrown by assertSeoHealthy when a report does not pass.