JavaScript is the reason your site looks amazing, and it's the reason a disturbing number of your pages look like blank slates to a crawler. That's not a reason to hate the framework — Next.js is genuinely great. But it is a reason to understand exactly where the framework delivers HTML and where it leaves the work to the user's browser. Because a crawler is not a user's browser.
The problem: two renders
Here's the core issue. Google can render JavaScript, but it does it as a second, separate pass — it fetches the HTML, then later runs the JavaScript to see what's really there. That second pass is slower, scheduled differently, and doesn't always finish.
So the difference between a page that "just works" and one that's effectively invisible comes down to one deceptively simple question: does the important content arrive in the initial HTML response, or does it only exist after a script runs?
What that means in practice
- If your page is client-side rendered (CSR) — a shell of an HTML page, with React injecting everything after load — the crawler sees mostly nothing on the first pass. You're gambling on that second render, and sometimes you lose.
- If your page is server-side rendered (SSR) or static (SSG), the meaningful content — the text, the meta, the structure — is in the first HTML bytes. The crawler reads it immediately. No gamble.
The fix isn't "stop using React." It's "stop making crawlers wait on the browser."
The checklist for a crawlable Next.js site
- Render on the server by default. Use static generation where content is known at build time, server rendering where it changes, and only use client rendering for the genuinely interactive bits.
- Ship metadata server-side. Title, description, and Open Graph should exist in the HTML response, not be injected by a client-side library after the fact.
- Don't hide content in requirements. If your key text only appears after a click, a scroll, or a state change that a bot never triggers, it doesn't exist for SEO.
- Watch lazy-loading. Loading critical content "for performance" can accidentally hide it from crawlers. Lazy-load your images, not your meaning.
- Verify with a no-JS view. Fetch your page without executing JavaScript and ask: would I understand what this page is about? If not, a crawler is struggling too.
The mental model
People, crawlers, and performance all want the same thing: the important stuff up front. When you optimize for "meaningful HTML in the first response," you get a site that loads fast for users, renders clean for bots, and never bets a render budget on a second pass.
JavaScript isn't the enemy. Architecture that makes crawlers gamble is. And that's a choose-your-render-strategy problem, solvable in Next.js cleanly.
We build and fix Next.js sites at Launch at Dawn and we test them the way crawlers actually read them. Book a free website teardown and we'll show you what your own pages look like to a bot that isn't running your JavaScript.