Skip to content
Marketing
Skill

/seo-rendering

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

From plugin
claude-seo-ai
8734 skills5 agents1 hook

Claude Code

$ npx -y skills add Hainrixz/claude-seo-ai --skill seo-rendering --agent claude-code

SKILL.md

seo-rendering.SKILL.md
name: seo-rendering
description: 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.
allowed-tools: Read, Grep, Glob, WebFetch, Bash

<!-- 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`: 1. **Content delta**: diff `raw_html_path` vs `rendered_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. 2. **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). 3. **Hydration-blocked text**: primary content present in raw HTML but hidden/empty until hydration, or rendered only into a client-only island. 4. **Lazy-loaded main content**: above-the-fold or primary content that requires scroll/intersection/interaction to load — invisible to a non-interacting crawler. 5. **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 `revalidate` interval or assert a strategy choice. Every finding carries `fixable: advisory`.

Verification

  • `render_diff`: compute the content-delta ratio of `raw_html_path` vs `rendered_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_path` requires a headless-browser data tier. When that tier is unavailable, status is `needs_api` — never a false `pass`.

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 in `rendered_html_path`; the raw HTML is an empty shell (`fail`, severity 5, axis `both`, `fixable: advisory`, confidence `established`). 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**, axis `ai`, `fixable: advisory`, confidence `established`).
  • `M4.render.lazy_main_content` — primary content loads only on scroll or interaction (`warn`, severity **3**, axis `both`, `fixable: advisory`, confidence `directional`).
  • `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, axis `both`).

Each finding: `evidence.observed` quotes the raw-vs-rendered delta on the page; `verification.reproduce` is a runnable `render_diff` assertion; `expected_impact` is 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
Read more
@hainrixz
Ships withclaude-seo-ai

The SEO + AI-search (GEO/AEO) optimization toolkit for Claude Code — two-score audit + opt-in fixer. Built for 2026-2027.

8734 skills5 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
87
Star history of Hainrixz/claude-seo-ai on GitHub, a chart by star-history.com

Other skills on claude-seo-ai.

audit

audit

Audit a website or web codebase for SEO and AI-search (GEO/AEO) — produces two independent 0-100 scores (Search SEO + AI…

compare

compare

Compare a site against its own baseline, against a staging deployment, against up to four competitors, or against the pages that…

fix

fix

Opt-in fixer (the /claude-seo-ai:fix command). Applies the safe, deterministic SEO/AI-search fixes from a persisted audit to the…

geo

geo

Analyze and score only a page's AI-search visibility (GEO/AEO) — answer extractability, fact density, AI-crawler access and…

score

score

Recompute and display the two scores (Search SEO + AI Visibility) from a persisted audit run, without re-crawling. Use to re-show…

More skills from other plugins.

seo

seo

Comprehensive SEO analysis for any website or business type. Full site audits, single-page analysis, technical SEO (crawlability,…

@agricidaniel@agricidanielInstall Skill
brag

brag

Turn the current project website into a short, polished, shareable launch video using Hyperframes. Use when someone says "/brag",…

brag3w21k
@latent-spaces@latent-spacesInstall Skill
geo-audit

geo-audit

Full website GEO+SEO audit with parallel subagent delegation. Orchestrates a comprehensive Generative Engine Optimization audit…

Questions about seo-rendering.

Which coding agents can use seo-rendering?
seo-rendering installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.