{"slug":"no-js-visibility-fix","name":"No-JavaScript Visibility Fix","version":"1.0.0","updated_at":"2026-11-06T07:42:46.978Z","use_when":"Finds which layer keeps a page's text out of the first HTML response, so a reader that does not run JavaScript sees an almost empty page, and gives the fix for that framework or host. Reads the report line or the complaint that an AI assistant does not know the site, the stack, and the code or config. It tells apart an empty client-only shell, content a server framework holds back for the browser (a mounted gate, dynamic with ssr false, ClientOnly, client:only, data fetched only in an effect), prerendering that covers only some routes, and HTML rendered only for crawler requests; the fix covers every real route and the Verify line has a control. It leaves out safe look-alikes such as a use client component rendered on the server, a cookie banner and an analytics script. One line per finding, or exactly No findings. Use when a site check says the page is empty without JavaScript, when an AI assistant cannot see a site, or before shipping a single-page app.","not_for":"Missing pages that answer 200, bots that get a 403 or a challenge, stale cached pages, and frameworks or hosts not named in the skill, which get a fix in the same shape marked unchecked. It reads the pasted files and the report line; it does not fetch your site.","languages":["en"],"tags":["javascript-seo","prerender","ssr","nextjs","nuxt","vite","ai-crawlers"],"category":"seo","category_url":"https://aiskills402.com/categories/seo","keywords":["first HTML response","ClientOnly","AI assistant"],"faq":[{"q":"How many causes are there, and what are they?","a":"Four, each under a fixed label: an empty client-only shell that nothing renders to HTML, a server framework that holds the text back for the browser, prerendering that covers only some routes, and HTML rendered only for crawler requests. A noscript line or hidden copy is called a stop-gap, never the fix."},{"q":"Why does the fix name every route?","a":"The tempting fix is applied to the home page only, and the report then turns green on that page while every deeper page stays empty. Each answer line names the routes the fix covers. The Verify line asks for a second, deeper route and for a 200 reply that is no challenge page, since a check without them also passes on a site that is broken for everyone."},{"q":"Does it help Claude Sonnet?","a":"Slightly. On five cases (a Next.js layout gate, a React Router site whose prerender skips the posts, a plain Vite app, an older Lovable project and a clean Astro site) Sonnet alone solved four, and Haiku alone also four. Both stumbled on one: the Lovable host prerenders only for verified crawlers, and they advised adding a plugin. With the skill both solved all five in content."},{"q":"What does a clean site return?","a":"The reply is the fixed sentence No findings., alone on its line, which a script can match against a single string. A cookie banner, an analytics script, a noscript tracking pixel and a client-side search box on a page whose text is already in the HTML earn no line and no remark."}],"examples":[{"lang":"en","model":"claude-sonnet-5-5","input_excerpt":"Report line: GET https://studio.example/ → 31 characters of visible text\nStack: next. Next.js 15 App Router on a Node host. Real routes: /, /pricing and /journal/<slug>, for example https://studio.example/journal/clay-glazes.\n\n--- app/layout.tsx\nimport { Shell } from \"@/components/Shell\";\nimport { CookieBanner } from \"@/components/CookieBanner\";…","output_excerpt":"CONTENT-CLIENT-ONLY — components/Shell.tsx, `if (!ready) return <div className=\"spinner\" aria-hidden=\"true\" />` with `ready` set only in `useEffect` — effects do not run during server rendering, so the first response holds only the spinner div and none of the `{children}` for any route — remove the `ready` gate so Shell renders `<Header />` and `<main>{children}</main>` on the server (keep any…"}],"page_url":"https://aiskills402.com/skills/no-js-visibility-fix","markdown_url":"https://aiskills402.com/skills/no-js-visibility-fix.md","image_url":"https://cdn.aiskills402.com/og/skills/no-js-visibility-fix/647dcf14.png","related_url":"https://api.aiskills402.com/v1/skills/no-js-visibility-fix/related","purchases_count":null,"tested":{"date":"2026-11-06","strong":{"model":"claude-sonnet-5-5 (Claude Code alias \"sonnet\")","verdict":"Right on all 5 cases, read by hand. On a Next.js app it found the ready gate in the shared shell component, said that the use client mark on the page was not the cause, and covered every route; on a React Router site on static hosting it saw that prerender true leaves out the journal posts and listed them from the content file; on a plain Vite app it named the empty root, did not offer the noscript line as a fix and called copy in index.html a stop-gap for the home page; on an older Lovable project it said the host prerenders only for verified crawlers, sent the owner to the TanStack Start upgrade and told them not to add a prerender plugin; on a clean Astro docs site it answered exactly No findings."},"weak":{"model":"claude-haiku-5-5 (Claude Code alias \"haiku\")","verdict":"Right on 4 of 5 cases by the skill's own format checks, read by hand, but it missed the one-line format on the plain Vite case: the cause, the fix and the routes were correct, yet it added two extra lines after the Verify line, one listing what is not a finding and one listing what it could not check. It named the right layer on the Next.js, React Router and Lovable cases, kept the cookie banner and the tracking pixel out of every finding, and answered exactly No findings on the clean Astro site."},"note":"Five cases written by us (four planted, one clean): a Next.js app whose layout shell returns a spinner until an effect runs, a React Router site on static hosting whose prerender setting leaves out the dynamic journal pages, a plain Vite app with an empty root and a noscript line, an older Lovable project, and a clean Astro docs site. Each planted case gives only what the owner has before the diagnosis (a report line, the stack name and several real files, the guilty one among them with no comment pointing at it) and carries one trap and one safe look-alike (the use client mark on the page and a cookie banner loaded by script; a client-side search box; a tracking pixel in noscript and an analytics script; a chat widget and an analytics script). Each answer is scored by code for the skill's format, and the same answers are scored for content only (cause named, the fix avoids the trap and covers the real routes, a no-JavaScript check on a second route) so that the side without the skill can be compared. Facts were read on 6 November 2026 from the public pages of Google, Vercel, Next.js, React, Nuxt, Astro, React Router, Vite, Vike and Lovable; one fact the brief suggested, that a Vite SSR plugin was renamed, was not on any page read and was dropped. There are no owner-measured facts. One check was widened after the run for both sides: the forbidden-pattern check for copy put into noscript now needs copy, text or a headline to go into the tag, so an answer that only said to drop the noscript message is not flagged. One run per model and case.","baseline":{"date":"2026-11-06","rows":[{"label":"Cases fixed right (5 cases)","better":"higher","strong":{"with":{"n":5,"of":5},"without":{"n":4,"of":5}},"weak":{"with":{"n":5,"of":5},"without":{"n":4,"of":5}}}],"note":"Scored on content only. Read by hand, Sonnet without the skill found the ready gate in the Next.js shell and said the use client mark on the page does not empty the HTML, listed the journal slugs for prerender on the React Router site, named the empty root on the Vite app without making noscript the fix, and called the Astro site fine. It missed the Lovable case: it said Lovable cannot render on the server and advised a prerender plugin, with no word about prerendering for verified crawlers. Haiku did the same on all five, including the plugin advice. The skill added that one fact to each model, plus a fixed code per cause and the exact sentence for a clean input."},"report_url":null},"price_usd":"0.02","price_micro":20000,"size_bytes":13888,"sha256":"b331cc6a8413879f1da1b3740a55aa7e37c38f8c9cbfb54a901de69ced797f17","outline":["The answer","How to find the layer","What is NOT a finding","The codes","What each framework documents","Rules","Work in this order","Short example"],"license":{"summary":"Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing","holder":"Georgi Kalchev, aiskills402.com","url":"https://aiskills402.com/docs#license"},"buy_url":"https://api.aiskills402.com/v1/skills/no-js-visibility-fix/file","redownload_url_template":"https://api.aiskills402.com/v1/purchases/{token}","mcp_tool":null,"payment":{"protocol":"x402","scheme":"exact","asset":"USDC","selling":true,"network":"base","network_caip2":"eip155:8453","pay_to":"0xbc0dcc70d8b5d85541d86ffc68d988fd59c22e68","facilitator":"cdp"},"seo_title":"Fix a Page Empty Without JavaScript","seo_description":"Finds which layer keeps your text out of the HTML that crawlers and AI tools read, then fixes it for Next.js, Nuxt, Vite or Lovable. Pay $0.02 once, in USDC.","versions":[{"version":"1.0.0","date":"2026-11-06","changelog":"# Changelog\n\n## 1.0.0 — 2026-11-06\n\nFirst release. Ordered by the site checker after it found that most live sites ship a page that is nearly empty without JavaScript. The idea is ours; no foreign skill was opened, facts come from the public documentation of each framework and host (see notes/ideas.md). Output: one line per finding with a fixed code, then one Verify line, or exactly `No findings.`\n\nTest: five cases written by hand (four planted, each with one trap and one safe look-alike, one clean control), one run on Claude Sonnet and one on Claude Haiku with the skill, and the same runs without it. Content gain over the side without the skill: one case for Sonnet (5 of 5 against 4 of 5) and one for Haiku, the older Lovable project, so the price is $0.02. Haiku with the skill added two extra lines to the answer on one case, which the format check counts as a miss (4 of 5 by format). One check was widened after the run for both sides (copy put into noscript). `test/control.mjs` shows that the checks pass on the ideal answers and fail on realistic wrong ones, on both sides. See `test-summary.json`.\n\nBefore release one sentence in \"How to find the layer\" was reworded (same rule, the layers are still read top to bottom and the first that explains the empty page wins), because its wording matched a free article on the site word for word; the models were not run again for that change.\n"}]}