When JavaScript Breaks Your SEO
You can ship a JavaScript-heavy single-page application to static.app and it'll work fine for users. Search engines, though, can struggle to see what's on the page. If you built your website as a React app, a Vue app, or anything similar, this article is for you.
The "view source" test
Open your website in Chrome. Right-click anywhere on the page and choose View page source. You'll see the raw HTML the server sent.
If you see your actual content (headings, paragraphs, product descriptions), you're fine. Google reads this directly.
If you see something like this:
<body> <div id="root"></div> <script src="/static/js/main.js"></script> </body>
You have a problem. The page content doesn't exist until JavaScript runs. Search engines may eventually render it, but indexing is slower, less reliable, and worse than for plain HTML.
What "client-side rendering" means
Two ways to put content on a web page:
- Server renders HTML, ships it to browser. Browser displays it immediately. This is what plain HTML does. Search engines love it.
- Server ships empty HTML and JavaScript. Browser runs JS, JS builds the page. This is what default React, Vue, and Angular apps do. Search engines have to do extra work.
Google can run JavaScript and see the rendered content, but with caveats. Rendering happens in a second pass, sometimes days after the initial crawl. Bing and most AI crawlers handle JavaScript worse than Google does. If your website is JavaScript-only, you're losing visibility on every search engine except Google, and even there you're slower to index.
The fixes, in order of preference
1. Use a static website generator. Astro, Eleventy, Hugo, Jekyll, Next.js with static export, Nuxt with static generation. These tools let you write your website in a modern framework, then output plain HTML files at build time. You upload the HTML to static.app and search engines see real content.
For a small website, Astro is a good choice. For a content-heavy website, Eleventy or Hugo. For a React-based website you already started, Next.js with next export or Gatsby. All of them produce static HTML that works on static.app.
2. Pre-render specific routes. If you can't migrate your whole app to a static generator, tools like Prerender.io will render your JavaScript app on demand and serve search engines the HTML version. It's a paid service, but cheaper than rebuilding.
3. Avoid JavaScript-only content. Use JavaScript for interactive bits (form validation, modals, sliders) but not for the page's main content. Write the actual product description, the article text, the headings in HTML. Layer JavaScript on top for the interactive parts.
4. Server-side rendering (not possible on a pure static host). True SSR needs a server that runs your framework on each request. Static.app doesn't do this; that's not what static hosting is. Server-side languages like PHP, Python, Ruby, and C++ aren't supported on the platform (grayed-out file types are the giveaway). If you absolutely need SSR, you'll need a different hosting model. Most of the time, static website generation is what you actually want, not SSR.
For a list of the JavaScript frameworks the platform officially supports for client-side apps (React, Vue, Angular, Next.js, Svelte and others), see What are JavaScript Frameworks? in the help center.
How to check whether Google sees your content
Open Google Search Console. Use the URL inspection tool. Click "Test live URL." When the test finishes, look at the "Screenshot" tab and the "More info" → "HTML" view. This shows you exactly what Google sees when it crawls your page.
If the HTML view shows your content, you're good. If it shows an empty shell, you have the problem this article describes.
The hydration trap
Some frameworks claim to do "static generation with hydration." This means the HTML is pre-rendered at build time, but JavaScript still runs in the browser to make it interactive.
That's fine for SEO. Search engines see the rendered HTML. Users get the interactivity. Best of both worlds.
The trap is when you accidentally configure the framework to skip the static generation and ship a client-only app. Always check the output. If you see real content in your HTML files, you're set. If you see <div id="root"></div> , the build didn't generate static pages.
The simplest rule
Real HTML in the source = guaranteed indexable. JavaScript-rendered content = a gamble. When in doubt, ship more HTML.