JavaScript SEO: A Broke Founder's Guide to Getting Indexed (2026)
Javascript SEO explained for bootstrapped founders — what matters, what to skip, and how to ship faster.
Table of contents7 sections
The Blank Page That Cost Me Three Weeks
In 2023, when I was building Clickly — my URL shortener that never quite launched — I did something I’m still a little embarrassed about. I built the entire marketing site as a client-rendered React app. Landing page, pricing, a little blog, all of it. A beautiful single-page app. Snappy transitions. Felt like a real product.
Then I did what every founder does at 1 AM: I opened Google, typed my domain, and searched for my own product name.
Nothing. Not on page one. Not on page five. My homepage wasn’t even in the index.
I panicked. I checked my hosting. I checked DNS. I resubmitted the sitemap four times like a man pressing an elevator button that’s already lit. Then I did the one thing I should’ve done first — I ran the URL through the Google Search Console inspection tool and clicked “view rendered HTML.”
It was blank. A <div id="root"></div> and nothing else. That’s what Google saw. That’s what I’d been shipping to the most important reader I’d ever have. An empty box.
That night taught me more about JavaScript SEO than any documentation ever did. So let me save you the three weeks.
What Google Actually Does With Your JavaScript
Here’s the part everyone gets wrong, in both directions. Some people think Google can’t run JavaScript at all (false, it’s been able to for years). Others assume it runs your JS instantly and perfectly (also false). The truth sits in an annoying middle.
Google processes a page in two waves. First it crawls the raw HTML your server sends — whatever text, links, and headings are literally in the response. Then, separately, it queues your page for rendering: it runs your JavaScript in a headless Chromium browser (the same evergreen engine that powers Chrome, kept up to date since 2019), and only then does it see the content your JS painted onto the page.
The good news, and it’s genuinely good: Vercel ran a study across more than 100,000 Googlebot fetches and found Google rendered essentially 100% of the pages it crawled, with a median rendering delay of about 10 seconds — not the “days or weeks” panic you read in old blog posts. The rendering queue is real, but for most pages it’s fast.
So if Google renders everything anyway, why did my Clickly homepage show up blank?
Because “Google can render it” and “Google will index it well” are two different sentences. That second wave is a tax. On the first crawl, a pure client-rendered app gives Google an empty shell — no content, no links to follow. Google has to spend rendering budget to discover what’s even on your page. For a brand-new domain with zero authority (hello, every one of my products), that budget is thin and that delay stretches. Vercel’s own conclusion: server-rendered pages get immediate link discovery, client-rendered ones have to be rendered before Google can even find your internal links.
You’re not blocked. You’re just standing at the back of the line, wearing a blindfold, on a site nobody’s heard of yet. That’s a bad place to fight for distribution.
Why This Is Really a Distribution Problem
I keep coming back to one idea across everything I write: distribution is the war, not the product. In 2026 you can clone a $15K/month SaaS in a weekend. What you can’t clone in a weekend is people finding it.
For a bootstrapped B2B founder, organic search is one of the few distribution channels that doesn’t cost money you don’t have. Ads are a black hole — the CAC will eat you alive before you find product-market fit. Reels only work for consumer apps. Which leaves content and free tools, and both of those live or die on one thing: Google actually indexing your pages.
So when you build your marketing site as a client-rendered SPA, you’re not just making a technical choice. You’re quietly kneecapping the cheapest distribution channel you have. You spent six months building. You wrote the blogs. And then you handed Google a <div id="root"> and wondered why the traffic never came.
That’s not an SEO bug. That’s a business wound, self-inflicted.
CSR vs SSR vs SSG (Without the Jargon Headache)
Three acronyms, and honestly the whole decision comes down to where the HTML gets built.
CSR — Client-Side Rendering. The server sends a near-empty HTML file plus a big JavaScript bundle. The user’s browser downloads it, runs it, and builds the page. This is your classic React or Vue single-page app. Great for a dashboard behind a login. Terrible for a public marketing page you want ranked.
SSR — Server-Side Rendering. The server runs your JavaScript and sends fully-formed HTML on every request. Google gets real content on the first crawl, no rendering tax. This is Next.js in its natural habitat.
SSG — Static Site Generation. You render everything to plain HTML files at build time, once. When Google (or a user) asks for a page, it’s already sitting there, pre-baked. Fastest possible response, and Google gets 100% of your content instantly. This is what Astro was born to do.
Here’s the founder-brain version:
| Content type | Render style | My pick | Why |
|---|---|---|---|
| Blog, landing, pricing, docs | SSG | Astro | Pre-built HTML, zero render tax, ships fast |
| Logged-in app / dashboard | SSR or even CSR | Next.js | It’s behind auth — Google never sees it anyway |
| A pure client-side marketing SPA | CSR | nobody, please | You’re fighting Google for no reason |
Notice the pattern. The pages you need indexed should be rendered on the server (or pre-rendered at build). The pages that live behind a login can be whatever you want, because SEO was never going to touch them. This is the exact same conclusion I landed on in Next.js vs Astro for your SaaS — I just arrived at it that time through pain, not planning.
Hydration: The Part That Fools You
Now the sneaky one. Modern frameworks do something called hydration. The server sends real HTML (good!), and then JavaScript “hydrates” it — attaches all the interactivity, event handlers, and state on top of that HTML in the browser.
This is why an SSR or SSG page gives you the best of both worlds: Google gets the full HTML immediately, users get an interactive app a moment later. That’s the whole trick. That’s why I stopped fighting frameworks and just let Next.js and Astro do their thing.
But here’s where founders shoot themselves in the foot: they build an SSR app and then stuff the actual content behind a client-side fetch that only fires after hydration. Your reviews load from an API on mount. Your product descriptions come from a useEffect. The HTML shell renders instantly, sure — but the words you actually want ranked show up only after JavaScript runs. You’ve technically got SSR and you’ve still handed Google a half-empty page. I’ve done this. It’s maddening because everything looks fine in your browser.
The fix is boring and it works: the content you want indexed must be in the server response, not fetched afterward. If a human turned off JavaScript and still saw your headline, your pricing, and your body copy — Google’s happy too.
The Practical Checklist (What I Actually Do Now)
No fluff. This is the list I run through before I let any site call itself “launched.”
- Marketing pages render HTML on the server. Astro for content sites, Next.js if the marketing pages live in the same app as the dashboard. Never a raw CSR SPA for anything you want found.
- Content lives in the initial HTML, not a post-hydration fetch. View source (Cmd+U). If your headline isn’t in there as text, neither is your ranking.
- Use the URL Inspection tool in Search Console. “View crawled page” and “View tested page” show you the exact HTML Google sees. This is truth. Your localhost is a liar.
- Real
<a href>links, notonClickrouter pushes for navigation. Google followshref. It does not click your buttons. If your only way between pages is JavaScript, your internal linking is invisible. - Server-render your titles, meta descriptions, and canonical tags. If those are set by JS after load, you’re gambling on the render wave getting them right. Don’t. (Google Search Central even tightened its guidance on JS-set canonicals in 2025 — read it as a warning, not a green light.)
- One more thing for 2026: Googlebot renders JS, but most AI crawlers — the ones feeding answer engines and LLMs — do not. They read raw HTML only. If you care about showing up in AI answers (and you should, that’s a distribution channel forming right now), server-rendered HTML isn’t optional anymore.
The Bottom Line
I spent three weeks convinced my hosting was broken, my DNS was cursed, my sitemap was haunted. The real problem was one architectural decision I made in an afternoon without thinking: I built a public marketing site as a client-only SPA, then asked Google to find it.
JavaScript SEO isn’t a dark art. It’s mostly one rule wearing a fancy costume: render your important pages on the server, so Google gets real content on the first look instead of an empty box it has to work to fill. Astro for content, Next.js for the app, and never a bare CSR SPA for anything you want ranked. Do that and 90% of the “JavaScript SEO problems” people agonize over simply never happen.
Your framework choice isn’t just about developer joy or bundle size. It’s about whether the cheapest distribution channel you have can actually see you. Get that right, and then go do the real work — the distribution grind that nobody can automate for you. If you’re still piecing the whole stack together on a shoestring, the broke solopreneur’s survival guide is the bigger picture.
This is the Broken Engineer Guide. I over-engineer everything, fail at business, and share the learnings so you win. Don’t ship Google a blank page. I did it for you.
