Audit
blume audit crawls the built site and reports SEO and site-health issues — every finding names the source file and front matter line that fixes it.
blume validate reads your content; blume audit reads the built site. It crawls the HTML in dist/ after a build and reports SEO and site-health issues — titles, meta descriptions, canonicals, Open Graph and X cards, headings, hreflang, images, the sitemap, robots.txt, and structured data.
Because Blume built the site, every finding names the source file and the front matter line that fixes it, not just the URL a crawler would see:
⚠ Meta description too long or too short 5 pages
/docs/configuration/export content/docs/configuration/export.mdx:3
fix: Rewrite `description` in the frontmatter to fit the length range.
Run it after a build:
blume build
blume audit
Findings are grouped by check rather than listed per page, so the report reads as a to-do list. Use --verbose to expand every affected page with its full detail, and --only/--skip to work through one category at a time. blume audit --list-checks prints the full catalog, which is also the check catalog at the end of this page — every finding’s docsUrl links to its entry there.
Flags
--fail-on error|warning|info— the CI gate: exit non-zero at this severity or above. Defaults toerror;--strictis an alias for--fail-on warning.--url <origin>— also probe a live deployment for status codes, response headers, and redirect chains.--external— probe outbound links over the network.--only <check|category>/--skip <check|category>— narrow the report to, or away from, these checks or categories (comma-separated). A term that names no check or category is an error that suggests the closest one, so a typo can’t quietly empty the report.--list-checks— print every check the audit can report, then exit.--verbose— list every affected page with each finding’s full detail, instead of the first few.--json— emit the report as JSON on stdout.--claude/--codex— hand the findings to Claude Code or Codex to fix interactively.
Failing CI
The exit code is the contract. By default blume audit fails only on errors — things that are definitely broken, like a link to a page that was never built, a redirect loop, or an invalid sitemap. Advisory findings (a short description, a duplicate title) are warnings and do not fail the build:
blume audit # fails on errors
blume audit --fail-on warning # also fails on warnings
Checking a live deployment
Some things only the real server can tell you: whether a page that exists in dist/ actually 404s behind a bad rewrite, whether responses are compressed, and whether an X-Robots-Tag header is quietly deindexing a page whose HTML looks perfectly fine. Point the audit at a deployment to add those checks:
blume audit --url https://docs.example.com
blume audit --url https://docs.example.com --external # also probe outbound links
Outbound links are graded rather than flatly failed: a 404 is a broken link you can fix, while a 403 or 5xx is usually rate limiting or someone else’s outage and is reported as a warning.
Fixing the findings with an agent
If you use Claude Code or Codex, the audit can hand its findings straight to it:
blume audit --claude # or --codex
This writes the complete JSON report — every affected page, not the terminal’s three-page preview — to a file and opens the agent interactively with a prompt that walks it through the findings: edit the source file each finding names, apply its suggested fix, then run blume build and blume audit again until the report is clean. The session is interactive by design: you review the edits through the agent’s own permission flow, and the agent is told never to fix a finding by deleting content.
--only and --skip narrow the handoff the same way they narrow the report, so you can send one category at a time.
What it does and doesn’t check
The check set is deliberately narrower than a general-purpose SEO crawler’s. Much of what such a crawler reports cannot happen to a Blume site — it never emits rel=nofollow, and Vite’s content-hashed bundles are never missing or redirecting — and reporting those as permanent zeroes would just teach you to ignore the report.
Two limits worth stating plainly:
- Structured data is validated for well-formedness (valid JSON, a
@context, a@typeon every node). Blume does not validate against the full schema.org vocabulary or Google’s rich-results rules. - Core Web Vitals are not checked. They need a real browser, and a flag that quietly measured nothing would be worse than not having one — so
blume auditreports the layout-shift causes it can see offline (images with nowidth/height, oversized assets) and leaves the rest alone for now.
Anything the audit did not run is reported as skipped rather than silently passing:
⊘ network skipped — pass --url <origin> (11 checks)
⊘ external skipped — pass --external (2 checks)
Check catalog
Every check blume audit can report, grouped by category, with its default severity, the tier it runs in, and the fix the report suggests. --only and --skip accept these ids (without the BLUME_AUDIT_ prefix is fine too) or the category names.
Content
Title tag missing or empty
BLUME_AUDIT_TITLE_MISSING · error · from the built HTML
Fix: Add a title to the page’s frontmatter.
Multiple title tags
BLUME_AUDIT_TITLE_MULTIPLE · error · from the built HTML
Fix: Remove the extra <title> from the page’s layout or MDX.
Title too long or too short
BLUME_AUDIT_TITLE_LENGTH · warning · from the built HTML
Fix: Rewrite title in the frontmatter to fit the length range.
Meta description missing or empty
BLUME_AUDIT_DESCRIPTION_MISSING · warning · from the built HTML
Fix: Add a description to the page’s frontmatter.
Multiple meta description tags
BLUME_AUDIT_DESCRIPTION_MULTIPLE · error · from the built HTML
Fix: Remove the extra description <meta> from the page’s layout or MDX.
Meta description too long or too short
BLUME_AUDIT_DESCRIPTION_LENGTH · warning · from the built HTML
Fix: Rewrite description in the frontmatter to fit the length range.
H1 tag missing or empty
BLUME_AUDIT_H1_MISSING · warning · from the built HTML
Fix: Give the page a title — Blume renders it as the page’s <h1>.
Multiple H1 tags
BLUME_AUDIT_H1_MULTIPLE · warning · from the built HTML
Fix: Demote the extra # Heading in the body to ## — Blume already renders title as the h1.
Low word count
BLUME_AUDIT_LOW_WORD_COUNT · info · from the built HTML
Fix: Expand the page, or fold it into a larger one.
Heading levels skip (e.g. h2 to h4)
BLUME_AUDIT_HEADING_SKIP · info · from the built HTML
Fix: Adjust the heading to the next level down — skipped levels break table-of-contents nesting and screen-reader outlines.
Page is dated in the future
BLUME_AUDIT_FUTURE_DATED_PAGE · info · from the built HTML
Fix: Correct the date, or hold the page back until it is meant to be live.
Viewport not set
BLUME_AUDIT_VIEWPORT_MISSING · error · from the built HTML
Fix: Restore the viewport <meta> in your ejected layout.
Duplicates
Duplicate title
BLUME_AUDIT_DUPLICATE_TITLE · warning · from the built HTML
Fix: Give each page a distinct title — search engines show it as the result headline.
Duplicate meta description
BLUME_AUDIT_DUPLICATE_DESCRIPTION · warning · from the built HTML
Fix: Give each page a distinct description.
Duplicate pages without canonical
BLUME_AUDIT_DUPLICATE_CONTENT · warning · from the built HTML
Fix: Merge the pages, or set seo.canonical on all but one.
Indexability
deployment.site is not set
BLUME_AUDIT_SITE_NOT_SET · warning · from the built HTML
Fix: Set deployment.site in blume.config.ts to the site’s public URL.
deployment.site is inferred at deploy time
BLUME_AUDIT_SITE_INFERRED_AT_DEPLOY · info · from the built HTML
Fix: Audit a production-like build (e.g. VERCEL=1 VERCEL_PROJECT_PRODUCTION_URL=<host> blume build) or the deployment itself with --url <origin>. Do not hardcode deployment.site — the platform sets it on every deploy.
Page is noindex but declares a canonical
BLUME_AUDIT_CANONICAL_ON_NOINDEX · warning · from the built HTML
Fix: Drop the canonical from noindex pages — Google treats the pairing as contradictory and may ignore one of the two.
Draft page is in the build
BLUME_AUDIT_DRAFT_PAGE_PUBLISHED · warning · from the built HTML
Fix: Rebuild without --preview before deploying, or remove draft: true if the page is ready to ship.
Canonical URL missing
BLUME_AUDIT_CANONICAL_MISSING · warning · from the built HTML
Fix: Set deployment.site so Blume can emit absolute canonical URLs.
Non-canonical page
BLUME_AUDIT_CANONICAL_NOT_SELF · info · from the built HTML
Fix: Point seo.canonical at this page, or remove it to use the default self-canonical.
Canonical points to a broken or redirecting page
BLUME_AUDIT_CANONICAL_BAD_TARGET · error · from the built HTML
Fix: Point seo.canonical at a page that exists and doesn’t redirect.
Canonical protocol does not match the site
BLUME_AUDIT_CANONICAL_PROTOCOL_MISMATCH · error · from the built HTML
Fix: Use the same protocol in seo.canonical as in deployment.site.
Page is not indexable
BLUME_AUDIT_ROBOTS_META_UNEXPECTED · info · from the built HTML
Fix: Remove noindex from the page’s frontmatter if it should be indexed.
Page exceeds Googlebot’s 2 MB crawl limit
BLUME_AUDIT_HTML_TOO_LARGE · error · from the built HTML
Fix: Split the page — Googlebot stops reading an HTML document at 2 MB.
X-Robots-Tag header conflicts with the page’s robots meta
BLUME_AUDIT_ROBOTS_HEADER_CONFLICT · error · needs --url
Fix: Remove the X-Robots-Tag header, or align it with the page’s robots meta.
Links
Page has links to a broken page
BLUME_AUDIT_LINK_TO_BROKEN · error · from the built HTML
Fix: Fix the link target, or create the page it points at.
Page has links to a redirect
BLUME_AUDIT_LINK_TO_REDIRECT · warning · from the built HTML
Fix: Link straight to the destination instead of through the redirect.
Orphan page (only reachable from navigation)
BLUME_AUDIT_ORPHAN_PAGE · warning · from the built HTML
Fix: Link to this page from the body of a related page.
Internal link hardcodes the site’s own origin
BLUME_AUDIT_INTERNAL_LINK_ABSOLUTE · warning · from the built HTML
Fix: Use a root-relative path (/docs/x) so the link survives previews and basePath.
Page has nofollow outgoing internal links
BLUME_AUDIT_INTERNAL_LINK_NOFOLLOW · info · from the built HTML
Fix: Drop rel="nofollow" — it stops this page passing authority internally.
Double slash in URL
BLUME_AUDIT_DOUBLE_SLASH_URL · error · from the built HTML
Fix: Check basePath / deployment.base — a trailing slash there produces //.
Link fragment matches no id on the target page
BLUME_AUDIT_ANCHOR_BROKEN · warning · from the built HTML
Fix: Point the fragment at a heading that exists on the target page, or fix the heading it meant.
URL contains uppercase, underscores, or spaces
BLUME_AUDIT_URL_STYLE · info · from the built HTML
Fix: Rename the source file to a lowercase, hyphenated slug — and add a redirect from the old URL if it was already published.
Redirects
Broken redirect
BLUME_AUDIT_REDIRECT_BROKEN · error · from the built HTML
Fix: Point the redirect at a page that exists.
Redirect loop
BLUME_AUDIT_REDIRECT_LOOP · error · from the built HTML
Fix: Break the cycle in redirects — it never resolves.
Redirect chain
BLUME_AUDIT_REDIRECT_CHAIN · warning · from the built HTML
Fix: Point every hop straight at the final destination.
Meta refresh redirect
BLUME_AUDIT_META_REFRESH · warning · from the built HTML
Fix: Use a real redirect in blume.config.ts instead of a meta refresh.
Redirect source is also a real page
BLUME_AUDIT_REDIRECT_SOURCE_IS_PAGE · error · from the built HTML
Fix: Remove the redirect, or delete the page it shadows — the page wins and the redirect never fires.
HTTPS to HTTP redirect
BLUME_AUDIT_REDIRECT_TO_HTTP · error · needs --url
Fix: Redirect to the HTTPS URL.
Social cards
Open Graph tags missing or incomplete
BLUME_AUDIT_OG_INCOMPLETE · warning · from the built HTML
Fix: Add a description — Blume fills the rest of the Open Graph tags for you.
Open Graph image missing
BLUME_AUDIT_OG_IMAGE_MISSING · warning · from the built HTML
Fix: Set deployment.site to turn on generated OG images, or set seo.image on the page.
Open Graph image is not in the build
BLUME_AUDIT_OG_IMAGE_BROKEN · warning · from the built HTML
Fix: Point seo.image at a file that exists, or rebuild — a dead og renders as a blank card everywhere the page is shared.
Open Graph image is too small for large cards
BLUME_AUDIT_OG_IMAGE_SMALL · warning · from the built HTML
Fix: Use an image of at least 1200×630 — smaller ones render blurry or get cropped into small-card layouts.
Open Graph URL not matching canonical
BLUME_AUDIT_OG_URL_MISMATCH · warning · from the built HTML
Fix: Align og:url with the page’s canonical URL.
X (Twitter) card missing or incomplete
BLUME_AUDIT_TWITTER_CARD_INCOMPLETE · warning · from the built HTML
Fix: Set seo.x.handle in blume.config.ts so X can attribute the card.
Internationalization
HTML lang attribute missing
BLUME_AUDIT_HTML_LANG_MISSING · error · from the built HTML
Fix: Restore the lang attribute on <html> in your ejected layout.
HTML lang attribute invalid
BLUME_AUDIT_HTML_LANG_INVALID · error · from the built HTML
Fix: Use a valid BCP 47 tag (e.g. en, en-GB) for the locale.
Hreflang and HTML lang mismatch
BLUME_AUDIT_HREFLANG_LANG_MISMATCH · error · from the built HTML
Fix: The page’s <html lang> must match its own hreflang annotation.
Hreflang annotation invalid
BLUME_AUDIT_HREFLANG_INVALID · error · from the built HTML
Fix: Use a valid BCP 47 tag in the hreflang annotation.
Self-reference hreflang annotation missing
BLUME_AUDIT_HREFLANG_SELF_MISSING · warning · from the built HTML
Fix: A page’s hreflang set must include a self-reference.
X-default hreflang annotation missing
BLUME_AUDIT_HREFLANG_XDEFAULT_MISSING · info · from the built HTML
Fix: Add an x-default alternate pointing at the default-locale page.
Missing reciprocal hreflang (no return-tag)
BLUME_AUDIT_HREFLANG_NO_RETURN_TAG · error · from the built HTML
Fix: Every page in an hreflang group must link back to every other one.
Hreflang points to a broken, redirecting, or non-canonical page
BLUME_AUDIT_HREFLANG_BAD_TARGET · error · from the built HTML
Fix: Point the hreflang alternate at a page that exists and is canonical.
Hreflang group has a language conflict
BLUME_AUDIT_HREFLANG_CONFLICT · error · from the built HTML
Fix: Each language in an hreflang group must name exactly one page.
Assets
Missing alt text
BLUME_AUDIT_IMAGE_ALT_MISSING · warning · from the built HTML
Fix: Add descriptive alt text, or alt="" if the image is decorative.
Image broken
BLUME_AUDIT_IMAGE_BROKEN · error · from the built HTML
Fix: Fix the image path, or add the file to public/.
Asset file size too large
BLUME_AUDIT_ASSET_TOO_LARGE · warning · from the built HTML
Fix: Compress the asset, or serve a modern format (WebP/AVIF).
Image has no width/height
BLUME_AUDIT_IMAGE_MISSING_DIMENSIONS · warning · from the built HTML
Fix: Set width and height so the browser can reserve space (avoids layout shift).
Referenced script, style, or asset is missing from the build
BLUME_AUDIT_SUBRESOURCE_MISSING · error · from the built HTML
Fix: Fix the reference, or restore the missing file.
HTTPS/HTTP mixed content
BLUME_AUDIT_MIXED_CONTENT · error · from the built HTML
Fix: Load the subresource over HTTPS — browsers block mixed content.
Sitemap
Indexable page not in sitemap
BLUME_AUDIT_INDEXABLE_PAGE_NOT_IN_SITEMAP · warning · from the built HTML
Fix: Remove draft/hidden/noindex from the page’s frontmatter if it should be indexed.
Noindex page in sitemap
BLUME_AUDIT_NOINDEX_IN_SITEMAP · error · from the built HTML
Fix: A noindex page should not be advertised in the sitemap.
Non-canonical page in sitemap
BLUME_AUDIT_NON_CANONICAL_IN_SITEMAP · error · from the built HTML
Fix: List only canonical URLs in the sitemap.
Sitemap names a page that does not exist or redirects
BLUME_AUDIT_SITEMAP_BAD_URL · error · from the built HTML
Fix: Remove the URL from the sitemap, or build the page it names.
Sitemap has a syntax error or wrong format
BLUME_AUDIT_SITEMAP_INVALID · error · from the built HTML
Fix: Sitemaps must be valid XML in the sitemaps.org urlset format.
Sitemap exceeds 50 MB or 50,000 URLs
BLUME_AUDIT_SITEMAP_TOO_LARGE · error · from the built HTML
Fix: Split the sitemap — the limits are 50 MB and 50,000 URLs.
Sitemap lastmod is invalid or in the future
BLUME_AUDIT_SITEMAP_LASTMOD_INVALID · warning · from the built HTML
Fix: Use a real W3C date that is not in the future — search engines that catch a sitemap lying about freshness stop trusting its lastmod entirely.
Sitemap includes URLs out of its scope
BLUME_AUDIT_SITEMAP_OUT_OF_SCOPE · warning · from the built HTML
Fix: A sitemap may only list URLs on its own origin.
Sitemap is not accessible
BLUME_AUDIT_SITEMAP_NOT_ACCESSIBLE · error · needs --url
Fix: Make sitemap.xml reachable at the site root.
robots.txt
robots.txt missing
BLUME_AUDIT_ROBOTS_MISSING · warning · from the built HTML
Fix: Set seo.robots: true to generate robots.txt.
robots.txt has a syntax error
BLUME_AUDIT_ROBOTS_INVALID · error · from the built HTML
Fix: Every robots.txt line must be a Field: value directive or a comment.
robots.txt disallows a page that is in the sitemap
BLUME_AUDIT_ROBOTS_DISALLOWS_INDEXABLE · error · from the built HTML
Fix: A page can’t be both disallowed in robots.txt and advertised in the sitemap.
robots.txt does not reference the sitemap
BLUME_AUDIT_ROBOTS_SITEMAP_MISSING · info · from the built HTML
Fix: Set deployment.site so robots.txt can reference the sitemap.
robots.txt is not accessible
BLUME_AUDIT_ROBOTS_NOT_ACCESSIBLE · error · needs --url
Fix: Make robots.txt reachable at the site root.
AI discoverability
llms.txt missing from the build
BLUME_AUDIT_LLMS_TXT_MISSING · warning · from the built HTML
Fix: Rebuild — agents.llmsTxt is enabled but the build has no llms.txt. If that’s intentional, set agents.llmsTxt: false.
llms.txt lists a page the build does not serve
BLUME_AUDIT_LLMS_TXT_STALE_ENTRY · warning · from the built HTML
Fix: Rebuild so llms.txt matches the site — a stale entry sends an AI agent to a page that is not there.
Indexable page missing from llms.txt
BLUME_AUDIT_LLMS_TXT_PAGE_MISSING · warning · from the built HTML
Fix: Rebuild so llms.txt matches the site; if the page is deliberately excluded, mark it seo.noindex or sidebar.hidden.
No DNS-AID agent-discovery records
BLUME_AUDIT_DNS_AID_MISSING · info · needs --url
Fix: Publish a ServiceMode SVCB or HTTPS record at _index._agents.<host> with your DNS provider so agents can discover the site via DNS (DNS-AID).
DNS-AID records are not DNSSEC-authenticated
BLUME_AUDIT_DNS_AID_UNSIGNED · info · needs --url
Fix: Enable DNSSEC for the zone so validating resolvers return authenticated DNS-AID answers; if your DNS provider doesn’t support DNSSEC, the records still work unsigned.
Structured data
Structured data is not valid JSON
BLUME_AUDIT_JSONLD_INVALID · error · from the built HTML
Fix: The JSON-LD block must be valid JSON.
Structured data is missing required properties
BLUME_AUDIT_JSONLD_INCOMPLETE · warning · from the built HTML
Fix: Every JSON-LD node needs @context and @type.
Live deployment
4XX page
BLUME_AUDIT_HTTP_4XX · error · needs --url
Fix: The page is linked or in the sitemap but the deployment 404s it.
5XX page
BLUME_AUDIT_HTTP_5XX · error · needs --url
Fix: The deployment is erroring on this page.
Timed out
BLUME_AUDIT_HTTP_TIMEOUT · error · needs --url
Fix: The page did not respond in time.
Not compressed
BLUME_AUDIT_NOT_COMPRESSED · warning · needs --url
Fix: Enable gzip or brotli on the host.
Slow page
BLUME_AUDIT_SLOW_RESPONSE · warning · needs --url
Fix: The page was slow to respond.
External link is broken
BLUME_AUDIT_EXTERNAL_LINK_BROKEN · error · needs --external
Fix: Fix or remove the outbound link.
External link redirects
BLUME_AUDIT_EXTERNAL_LINK_REDIRECT · info · needs --external
Fix: Link straight to the destination.