audit-seo
Skill106 starsChanged 7 months agoMITView on GitHub
Audit SEO per pracht route (`head()` titles, descriptions, Open Graph, canonicals, robots) and generate a `sitemap.xml` from the route manifest. Use for "audit SEO", "check meta tags", "generate a sitemap", "check OG cards", "review robots.txt".
3 other projects use a version of this.
Adopted by
Most recently taken up by
- kostja94/openblogtheir own version, first seen Oct 26, 2026
- MrBridgeHQ/audit-seo-claudetheir own version, first seen Jul 5, 2026
- omardoucoure/claude-skillstheir own version, first seen Apr 4, 2026
Other versions3 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 3
- kostja94/openblog★ 7same name
- MrBridgeHQ/audit-seo-claude★ 0same name
- omardoucoure/claude-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository33 other files it gives its agents.
- AGENTS.mdAGENTS.md
- add-authSkill
- add-capabilitiesSkill
- add-contentSkill
- add-dbSkill
- add-i18nSkill
- add-imagesSkill
- add-observabilitySkill
- add-openapiSkill
- audit-a11ySkill
- audit-agent-surfaceSkill
- audit-authSkill
- audit-bundlesSkill
- audit-csrfSkill
- audit-depsSkill
- audit-headersSkill
- audit-islandsSkill
- audit-loadersSkill
- audit-redirectsSkill
- audit-secretsSkill
- audit-shellsSkill
- configure-isgSkill
- migrate-nextjsSkill
- pracht-debugSkill
- pracht-deploySkill
- pracht-scaffoldSkill
- pracht-test-apiSkill
- pre-deploySkill
- scaffold-e2eSkill
- scaffold-testsSkill
- tune-render-modeSkill
- typed-routesSkill
- upgrade-prachtSkill
The file
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 0 are distinctive, and 8 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 79
If absent, recommend creating public/robots.txt:
- Very specific: line 92
No accidental Disallow: / (full-site block).
- Very specific: line 110
Write each URL in the app's canonical spelling: /about/ under trailingSlash: "always", /about otherwise (the root is always /).
- Very specific: line 112
Default <changefreq> from the route's revalidate policy: timeRevalidate → weekly if > 86400s, daily if > 3600s, hourly otherwise.
- Very specific: line 126
If the user asks, scaffold JSON-LD via the head() export's native script field — HeadMetadata supports script?: HeadScriptDescriptor[], …
- Very specific: line 143
No shell-level custom <script> JSX is needed.
- Very specific: line 159
Use the resolved manifest — shell head() inheritance matters.
- Very specific: line 160
Never auto-write sitemap.xml to the deployed site without user confirmation.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Pracht Audit SEO
pracht owns the document. Per-route SEO lives in the head() export
returning { title?, lang?, meta?, link?, script? }. This skill audits
coverage and generates the static SEO artifacts.
Step 1: Inventory
MCP: if pracht dev-mcp is registered, prefer its inspect_*, doctor, and verify tools to the CLI.
pracht inspect routes --jsonPrerequisite: pracht inspect needs a vite config with the pracht plugin
wired up; run from the app root.
For every route file, read the head() export (and the shell's head() for
inherited values).
Step 2: Per-route checklist
For each route, capture presence and quality:
| Field | Expected |
title | 30-60 chars, unique per route |
meta description | 70-160 chars, unique per route |
meta og:title | Present (often = title) |
meta og:description | Present |
meta og:image | Absolute URL, ≥ 1200×630 |
meta og:url | Absolute, canonical |
meta twitter:card | summary_large_image for content |
link canonical | Absolute URL |
script (JSON-LD) | Optional; see Step 6 |
lang | Set on root or via shell |
Skip SPA-only / non-indexable routes (admin, dashboard) — flag as "noindex candidate" if they don't already declare it.
Step 3: Cross-route checks
- Duplicate titles across routes — list collisions.
- Duplicate descriptions — same.
- Missing canonical on any route that has any
?queryvariants. - Duplicate trailing-slash URLs. With the default
pracht({ trailingSlash: "ignore" })every page answers at/aboutand/about/. Recommend"always"or"never", which redirects the other spelling with a 308, or a canonical link on every page. Canonicals,og:url, and sitemap entries must use the spelling indist/server/routing.json. - Missing OG image — most common issue; recommend a default image at shell level so every route inherits one.
Step 4: robots.txt
robots.txt MUST be served at the origin root (/robots.txt) — crawlers
never look anywhere else. pracht API routes are always mounted under /api/
(a src/api/robots.ts handler serves /api/robots, never /robots.txt), so
an API handler cannot provide it. The workable option is the static asset:
public/robots.txt(Vite static asset, served at/robots.txt).
If absent, recommend creating public/robots.txt:
User-agent: *
Allow: /
Disallow: /api/
Disallow: /admin/
Sitemap: https://<domain>/sitemap.xmlIf present, validate:
- A
Sitemap:line referencing an existing endpoint (see Step 5 — if the sitemap is an API route, this must point at/api/sitemap). - No accidental
Disallow: /(full-site block). - Path patterns match real routes (cross-reference with the manifest).
- Flag any
src/api/robots.tsfound in the repo aswarn: it is dead weight at/api/robotsand does not serve/robots.txt.
Step 5: sitemap
Generate (or recommend generating) a sitemap from the route manifest:
- Include routes by indexability, not prefetch strategy: public
render: "ssg"/"isg"routes (and public SSR routes worth indexing), minus routes under auth middleware, minus routes declaring arobots/noindexmeta. (prefetchis a client navigation hint — orthogonal to indexability; do not use it as a criterion.) - Skip dynamic-segment routes unless
getStaticPathsresolved them at build time — pull resolved paths from the prerender output, which is laid out asdist/client/<route>/index.html(clean URLs; e.g./about→dist/client/about/index.html). - Write each URL in the app's canonical spelling:
/about/undertrailingSlash: "always",/aboutotherwise (the root is always/). - Default
<changefreq>from the route's revalidate policy:timeRevalidate→weeklyif> 86400s,dailyif> 3600s,hourlyotherwise.
Offer two output forms:
- Static
public/sitemap.xmlregenerated at build time via a small script (served at/sitemap.xml). - A pracht API route at
src/api/sitemap.tsthat emits XML on each request from the inspected manifest. It is served at/api/sitemap(API routes always mount under/api/), so the robotsSitemap:line must point athttps://<domain>/api/sitemap.
Step 6: Structured data (optional)
If the user asks, scaffold JSON-LD via the head() export's native script
field — HeadMetadata supports script?: HeadScriptDescriptor[], where each
descriptor takes attributes plus children for the inline body:
export function head() {
return {
script: [
{
type: "application/ld+json",
children: JSON.stringify({ "@context": "https://schema.org", ... }),
},
],
};
}No shell-level custom <script> JSX is needed. This is opt-in — do not push
it on every audit.
Step 7: Report
| Route | Severity | Title | Description | OG image | Canonical | Verdict |
Primary severity per finding: error (site blocked by robots, auth-gated
route in sitemap), warn (missing title/description/OG image/canonical on an
indexable route), info (nice-to-haves like JSON-LD). Keep the
complete/partial/missing verdict as a secondary per-route rollup,
grouped by verdict.
Rules
- Use the resolved manifest — shell
head()inheritance matters. - Never auto-write
sitemap.xmlto the deployed site without user confirmation; offer the file as a draft. - Recommend a default OG image at the shell level — single highest-leverage fix.
- Auth-gated routes should NOT appear in sitemaps.
- Cross-reference with
tune-render-mode— SSG routes are the sitemap candidates; SSR routes need decision per case.
$ARGUMENTS
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

