Search Engines & SEO

JavaScript SEO

Definition

Most generated single-file apps ship an almost empty HTML document: a head, a div with an id of root, and a script that builds everything else once a browser opens it. That is fine for a person and a problem for everything else. Googlebot deals with it in two waves — it crawls the raw HTML first and takes whatever is there, then queues the page for rendering in a headless Chromium instance and indexes what the script eventually produced. Rendering is deferred rather than immediate, and it is not guaranteed: pages can sit in the render queue, and a script that fails, times out or depends on a blocked resource leaves an indexed page containing nothing but that empty div. Other crawlers are stricter still, because most social and chat preview bots never execute JavaScript at all. The discipline is about making the important parts survive every one of those cases.

Why It Matters

The failure is invisible from your own browser. You open the link, the app loads, everything looks right — and the copy in the index is blank, or carries whatever placeholder title the generator left behind. The preview case is worse because it is immediate and public: paste a client-side-rendered link into Slack, LinkedIn, WhatsApp or a chat assistant and the card comes back with no title, no description and no image, because the bot fetched the HTML, found an empty container and stopped there. It does not wait for scripts, it does not run them, and it does not come back later to try again. A link that looks broken in the first place it is shared is a link nobody clicks.

How It Works

The first wave is a plain HTTP fetch: the crawler takes whatever HTML the server returns and pulls out links, the title, meta tags and any text already present. The page then enters a rendering queue, where a current headless browser loads it, runs the scripts, waits for the network to settle and treats the resulting DOM as the version to index. Anything the renderer cannot reach is lost — scripts blocked in robots.txt, files on a host that is down, content that only appears after a click. Links must be real anchor elements with an href, because a div with a click handler that pushes a route is not a link and will not be followed. Titles and meta tags injected by script are usually picked up in the second wave, but never by a preview bot, which is why they belong in the served markup. Check with the URL Inspection tool in Search Console, which shows the rendered HTML Google is actually holding, rather than trusting what your own browser draws.

Real-World Example

Someone generates a sales dashboard in a chat assistant, exports the single HTML file and publishes it at sales-view.99helpers.site. The file is 4 KB of markup and 300 KB of script. Shared in Slack it previews as a bare address with no title; inspected later, the rendered page has content but the indexed title is still the placeholder. Three fixes exist, in rising order of effort: put a real title, meta description and Open Graph tags in the head so every crawler sees them without executing anything; prerender the page once to static HTML and upload that instead; or move to a framework that renders on the server. For a generated single-file app the first fix takes two minutes and solves the preview problem outright.

Common Mistakes

  • Checking the page in your own browser and concluding it is fine — your browser runs the script, and the bot that builds the preview card does not
  • Leaving the framework's placeholder title in the head — that is what gets indexed and shared, and a preview bot never sees the version the script writes later
  • Using div elements with click handlers for navigation — crawlers follow href attributes, so routes reachable only by clicking are invisible
  • Assuming rendering is guaranteed because Google can render — it is queued, delayed and occasionally skipped, so nothing essential should depend on it

Related Terms

Put a file online in seconds

Drop in a document, an image, a page or a whole static website and share the link — free, with no build step and no server to set up.

Host a file free →