seo-rendering
Skill81 starsChanged 2 months agoMITView on GitHub
Audit a page's rendering strategy and JavaScript dependency — diff raw HTML against the rendered DOM to measure how much primary content, links, headings, and JSON-LD exist only after JS executes, classify CSR-only / SSR / SSG / ISR, and emit framework-specific guidance. Module M4. Feeds both the Search SEO and AI Visibility scores.
In this repository33 other files it gives its agents.
- auditSkill
- compareSkill
- fixSkill
- geoSkill
- scoreSkill
- seo-agent-readinessSkill
- seo-ai-crawlersSkill
- seo-ai-discoverySkill
- seo-core-web-vitalsSkill
- seo-crawlabilitySkill
- seo-crawl-renderSkill
- seo-ecommerceSkill
- seo-eeatSkill
- seo-entity-linkingSkill
- seo-fix-applySkill
- seo-freshnessSkill
- seo-geo-answerblocksSkill
- seo-geo-factdensitySkill
- seo-headings-structureSkill
- seo-images-mediaSkill
- seo-indexabilitySkill
- seo-internal-linkingSkill
- seo-internationalSkill
- seo-localSkill
- seo-meta-onpageSkill
- seo-mobileSkill
- seo-orchestratorSkill
- seo-platform-detectSkill
- seo-schema-jsonldSkill
- seo-scoreSkill
- seo-sitemapsSkill
- seo-social-cardsSkill
- seo-vertical-detectSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 21
AI gate: if the h1, primary body, or JSON-LD exist only in rendered_html_path, flag the page as not reliably consumable by non-JS AI …
- Distinctive: line 44
Don't claim "SSR ranks higher than CSR" as a ranking factor.
≈ “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
<!-- Portions Copyright (c) 2026 Enrique Rocha (@soyenriquerocha) - see LICENSE for original authors · tododeia.com · id er-d03758e1 -->seo-rendering (M4)
Content that only exists after hydration is invisible to any consumer that does not run JavaScript. Google renders JS (documented); most third-party AI crawlers are reported not to (directional — see Honesty), so a CSR-only shell is primarily an AI-visibility and crawl-efficiency problem. JS dependency also delays first paint; see references/cwv-thresholds.md for how this feeds LCP/INP.
Inputs
Work from the PageSnapshot named in your dispatch envelope: read parsed from <run_dir>/pages/<slug>.json and parsed_rendered, plus the render{needed,signals,used,confidence,hint,delta} block — the script already computed the raw-vs-rendered delta; raw_html_path/rendered_html_path name the files on disk; Grep pages/<slug>.html for verbatim evidence; site artifacts live in <run_dir>/site/{robots.json,sitemaps.json,discovery.json}. Deterministic findings already emitted by audit.mjs are listed in <run_dir>/findings.deterministic.json — do not re-emit those ids; add model-judged findings only. If invoked directly with a URL/path and no snapshot exists, first run node "${CLAUDE_PLUGIN_ROOT}/scripts/snapshot.mjs" <target> --out "${CLAUDE_PLUGIN_DATA}/runs" and use the printed snapshot path.
Audits
Working from the PageSnapshot (parsed_rendered when render.used is not none, else parsed) and the script-computed render.delta:
- Content delta: diff
raw_html_pathvsrendered_html_path— measure the share of primary text, internal links, headings (h1–h3), and<script type="application/ld+json">blocks that appear only after JavaScript runs. - Classify the strategy: CSR-only (empty/near-empty raw shell, content injected client-side) / SSR / SSG (prerendered static) / ISR (prerendered + revalidated). Use raw-HTML completeness and framework signals (
__NEXT_DATA__, hydration markers,data-reactroot, build manifests). - Hydration-blocked text: primary content present in raw HTML but hidden/empty until hydration, or rendered only into a client-only island.
- Lazy-loaded main content: above-the-fold or primary content that requires scroll/intersection/interaction to load — invisible to a non-interacting crawler.
- AI gate: if the h1, primary body, or JSON-LD exist only in
rendered_html_path, flag the page as not reliably consumable by non-JS AI crawlers.
Fixes (fixable: advisory)
Rendering strategy is a framework/architecture decision with high breakage risk, so M4 is ADVISORY only — it diagnoses and prioritizes, it never auto-edits build/server code.
- Emit framework-specific guidance: e.g. move CSR-only routes to SSG/ISR or SSR (Next.js App Router server components /
generateStaticParams+revalidate; Nuxt/Astro/SvelteKit equivalents). - Recommend prerendering or partial prerendering for primary content; reserve client-only islands for genuinely interactive widgets.
- Where the right strategy depends on data freshness or constraints the snapshot can't reveal, leave a clearly-marked TODO for the user — never fabricate a
revalidateinterval or assert a strategy choice. Every finding carriesfixable: advisory.
Verification
render_diff: compute the content-delta ratio ofraw_html_pathvsrendered_html_path(primary text / links / headings / JSON-LD present in rendered but absent in raw). A high delta on primary content confirms the JS dependency.- Rendering an accurate
rendered_html_pathrequires a headless-browser data tier. When that tier is unavailable, status isneeds_api— never a falsepass.
Findings
Emit findings per schema/finding.schema.json. Severity policy: 5 is reserved for catastrophic, eligibility-killing facts at site/template scope; 4 major · 3 moderate · 2 minor · 1 cosmetic · 0 informational — and only an established severity-5 fail in an active category can cap a score (references/scoring-model.md). Examples:
M4.render.csr_only_primary_content— the H1 and body text exist only inrendered_html_path; the raw HTML is an empty shell (fail, severity 5, axisboth,fixable: advisory, confidenceestablished). This is the module's only capping finding, and only at template/site scope.M4.render.jsonld_js_injected— JSON-LD blocks appear only after hydration, so a non-JS consumer sees no structured data (warn, severity 3, axisai,fixable: advisory, confidenceestablished).M4.render.lazy_main_content— primary content loads only on scroll or interaction (warn, severity 3, axisboth,fixable: advisory, confidencedirectional).M4.render.needs_renderer— the page shows CSR signals and no renderer was available, so the delta could not be measured (needs_api, severity 3, axisboth). Each finding:evidence.observedquotes the raw-vs-rendered delta on the page;verification.reproduceis a runnablerender_diffassertion;expected_impactis banded + confidence-tagged (no naked %).
Honesty
- Googlebot renders JavaScript — documented by Google (second-wave, queued rendering), so a well-built CSR app can still be indexed and rank. That part is
established; treat CSR-only as a risk to AI consumers and to crawl efficiency, not as an automatic Google failure. - "Most AI crawlers do not execute JavaScript" is
directional, not documented. Vendors publish user-agent tokens, not rendering capabilities. Word it as "we could not confirm that these crawlers execute JS, and their published behaviour suggests they do not" — never as a vendor statement. - Don't claim "SSR ranks higher than CSR" as a ranking factor. What is real is content availability to non-JS consumers and faster first paint, not a rendering-mode boost. Keep CSR where the page is interactive by nature and the primary content is still server-delivered.
- A render delta measured without a real headless browser is not a measurement — if the renderer tier was unavailable, say
needs_apirather than inferring the delta from framework markers alone.
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.

