InsightsBuilder guides

Why your Bolt app isn't showing up on Google

Bolt ships a working full-stack app in a browser tab, but a deployed SPA serves an empty HTML shell before JavaScript runs — and that's exactly what Googlebot and AI crawlers see. Here's what they actually receive and the four fixes in order.

Aug 8, 2026 · 6 min read

The short version

Bolt gives you a full-stack app in seconds, but it ships as a Vite/React SPA. The server returns one tiny HTML file with an empty root element and a script tag. Googlebot's first pass sees nothing; AI crawlers see nothing at all. Fix what the crawler receives — not what the browser renders.

What Google actually receives

Open your deployed Bolt app, use View Page Source (Cmd+U), and look at the root element. You'll see something like this:

what the crawler downloadshtml
<!doctype html>
<html lang="en">
  <head><title>Vite App</title></head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

No headline, no copy, no links, no meta description. A default Vite App title. Googlebot does render JavaScript on a second pass, but that pass can lag days behind and it skips pages it judges low-signal. The AI crawlers behind ChatGPT, Perplexity and Google's AI Overviews don't run JavaScript at all. To all of them, your page is blank.

The four fixes, in the order that matters

1. Serve real HTML (pre-render or switch to SSR)

The root fix. Your public, indexable pages need to return content in the first HTTP response — title, headings, body copy — before any JavaScript runs. If Bolt's export gives you a static build, put a pre-render step in your deploy that generates real HTML for each route. If you're on Netlify or Vercel, a simple SSR adapter can do it. The logged-in dashboard can stay client-rendered; it's the marketing, landing and public pages that need to be crawlable.

2. Set per-page title, description and Open Graph

Once real HTML is served, give Google something worth indexing. Every public page needs its own <title>, a <meta name="description">, and an Open Graph image so shared links unfurl with a real preview instead of a blank card.

html
<title>Split expenses with friends — Tabby</title>
<meta name="description" content="Track shared bills and settle up in a tap.">
<meta property="og:title" content="Tabby — split expenses">
<meta property="og:image" content="https://yourapp.com/og.png">

3. Add a sitemap.xml and robots.txt

A sitemap tells Google which URLs exist so it doesn't have to discover them by crawling through JavaScript. Generate one with your public routes, and reference it from robots.txt with Sitemap: https://yourapp.com/sitemap.xml. Without it, a JavaScript app with few inbound links can stay invisible for weeks.

4. Verify in Google Search Console and request indexing

Add the site to Search Console, submit the sitemap, and use URL Inspection on your key pages. Search Console is also where you'll see whether Google rendered the page successfully or skipped it because the HTML was empty.

The Bolt-specific gap: secrets in the client bundle

Bolt generates a front-end that often includes API keys and Supabase anon keys in the client JavaScript. Anyone who inspects the page source can read them. Actuant checks for leaked keys and server versions that shouldn't be public — this is one of the findings a repo scanner won't catch because it's only visible on the deployed URL.

How to tell it's working

  1. 1

    View source on a public page

    Cmd+U on your deployed URL. You should see your title, description and body copy in the raw HTML — not an empty <div id="root">.

  2. 2

    Run a site: search

    Google site:yourapp.com. Results (after a few days) confirm indexing is happening. Zero results means nothing was indexed yet.

  3. 3

    Check the sitemap in Search Console

    Look under Indexing → Sitemaps. A green "Success" on your sitemap means Google found and read it — the first step toward indexing.

How long until it ranks

Once real HTML is served and the sitemap is submitted, indexing typically starts within days. Ranking for anything competitive takes longer and depends on links and content — but you can't rank at all while the page is blank, so serving crawlable HTML is the single step that unblocks everything else.

Every fix above maps to a check Actuant runs against your deployed Bolt app: it loads the live URL in a real browser, reads the pre-JavaScript HTML, and returns each as pass or fail with the exact thing to change.