Puppeteer JS Rendering Auditor
Loads each URL as raw HTML and as a fully JavaScript-rendered DOM via headless Chrome, then diffs content, links, and m…
Updated
Use this skill
$ npx skills add seoskills.sh/puppeteer-render-auditorAbout this skill
Puppeteer JS Rendering Auditor is a Technical SEO skill for AI agents, published in the seoskills.sh catalog. Reach for it when your work involves crawlability, indexing, site architecture, Core Web Vitals, and log-file analysis. Install it with one command and it runs inside your own agent, so the work happens in your workflow, not a separate SEO tool.
SKILL.md
Puppeteer JS Rendering Auditor
AGENT ROLE: Autonomous rendering-parity agent. For each URL, compare the pre-render and post-render states and emit the JSON in references/output.schema.json. Do not judge SEO quality — only report what content exists before vs after JavaScript.
OBJECTIVE
Detect content, links, and metadata that appear ONLY after JavaScript executes, because a crawler that does not render (or renders on a delay) may never index them.
INPUTS
urls(REQUIRED, string[]): absolute URLs to audit.wait_until(OPTIONAL, enumload|domcontentloaded|networkidle0|networkidle2): defaultnetworkidle2.render_timeout_ms(OPTIONAL, default 15000).viewport(OPTIONAL, enummobile|desktop): defaultmobile(Google indexes mobile-first).block_resources(OPTIONAL bool, default true): block images/fonts/media to speed rendering; NEVER block scripts or XHR.
AUTHENTICATION / RUNTIME
- No external API key. REQUIRES a headless Chromium.
- IF
puppeteeris installed THEN use its bundled Chromium. - ELSE IF env
PUPPETEER_EXECUTABLE_PATHis set THEN launch that binary. - ELSE STOP
error.code="NO_CHROMIUM": "Install puppeteer or set PUPPETEER_EXECUTABLE_PATH to a Chrome/Chromium binary."
- IF
- Launch flags MUST include
--no-sandbox --disable-gpuin containerized environments.
EXPECTED TOOL CALLS (per URL)
- RAW:
fetch(url)(orpage.gotowith JS disabled) → captureraw_html. - RENDERED:
page.goto(url, {waitUntil, timeout})→page.content()→rendered_html. - Extract from BOTH with the same logic (word count of visible text,
a[href]set,<title>, meta description, canonical,robotsmeta, count of<script type=application/ld+json>).
PROCEDURE (deterministic, per URL)
STEP 1 — Fetch raw HTML. IF non-200 THEN record {url, status, error:"NON_200"} and continue to next URL.
STEP 2 — Render with Puppeteer. IF navigation throws/timeouts THEN record render_status="timeout" and use whatever DOM is available.
STEP 3 — Compute deltas:
text_delta_words = rendered_words - raw_words.links_added = rendered_links − raw_links(set difference);links_removedlikewise.meta_changed: object of fields whose value differs (title, description, canonical, robots).jsonld_added = rendered_jsonld_count − raw_jsonld_count. STEP 4 — CLASSIFYseverity:highIFtext_delta_words > 100ORlinks_added.length > 10OR canonical/robots differ.mediumIF any content or ≤10 links added.noneIF states are equivalent (good — content is in raw HTML). STEP 5 — EMIT per URL; overallstatus="ok".
RATE LIMITS & ERROR HANDLING
- Concurrency: render at most
3pages in parallel; reuse one browser instance, one page per task, ALWAYSpage.close()in a finally block to avoid leaks. - Per-URL failure is isolated — never abort the batch for one bad URL.
- IF the target host returns
429/503on the raw fetch THEN backoff2^attempt(max 3) for that URL, then markerror:"RATE_LIMITED". - Honor
robots.txt: IF a URL is disallowed for the default UA THEN skip withskipped:"robots_disallow"unlessrespect_robots=falseis explicitly passed.
MISSING / INSUFFICIENT DATA
- IF
rendered_htmlequalsraw_htmlbyte-for-byte THENseverity="none",note="no client-side rendering detected". - Never infer indexation status; only report the observable render delta.
OUTPUT
One JSON object per references/output.schema.json. No prose.
FILES
scripts/render_audit.js— Puppeteer reference implementation (raw vs rendered diff).references/output.schema.json— output contract.
Not using the CLI? Copy the SKILL.md and paste it straight into ChatGPT, Claude, or any agent.
Embed a badge
Install into your agent
More in Technical SEO
seo
Optimize for search engine visibility and ranking. Use when asked to "improve SEO", "optimize for search", "fix meta tags", "add structured data", "sitemap optimization", or "search engine optimization".
core-web-vitals
Optimize Core Web Vitals (LCP, INP, CLS) for better page experience using field and lab evidence. Use when asked to "improve Core Web Vitals", "fix LCP", "reduce CLS", "optimize INP", "page experience optimization", or "fix layout shifts".
opencli-browser-sitemap
Use when driving a website with opencli browser and sitemap context is available, requested, or needed to avoid blind navigation. Guides agents to consume site sitemap files lazily, choose adapter/browser fallback paths, resume from state signatures, and mark stale sitemap entries without trusting them over live browser state.
seo-sitemap
Analyze existing XML sitemaps or generate new ones with industry templates. Validates format, URLs, and structure. Use when user says "sitemap", "generate sitemap", "sitemap issues", or "XML sitemap".
seo-technical
Technical SEO audit across 9 categories: crawlability, indexability, security, URL structure, mobile, Core Web Vitals, structured data, JavaScript rendering, and IndexNow protocol. Use when user says "technical SEO", "crawl issues", "robots.txt", "Core Web Vitals", "site speed", or "security headers".
seo-page
Deep single-page SEO analysis covering on-page elements, content quality, technical meta tags, schema, images, and performance. Use when user says "analyze this page", "check page SEO", "single URL", "check this page", "page analysis", or provides a single URL for review.