1. Home
  2. Blog
  3. 3D web / WebGL

WebGL SEO: How to Make a Three.js or 3D Site Rankable

A 3D site can rank as well as any other, if the content lives in HTML and the canvas is decoration. Here's the checklist and how to verify it.

ASFARI Lab5 min readOctober 2026

A sheet of frosted glass with faint lines of type etched on it, standing in front of a glowing chrome sculpture, suggesting readable content in front of a 3D scene

WebGL SEO works when you treat the canvas as decoration and the HTML as the content. Google renders JavaScript, but a <canvas> is just pixels: as Utsubo puts it, it has "zero indexable text". So every headline, product detail, link and meaningful page state has to exist as server-rendered markup before the 3D boots. Do that, and a Three.js site can rank like any other.

Why canvas SEO fails by default

Most 3D sites that don't rank fail in one of four ways:

  1. Text inside the scene. Headlines modeled as 3D type or drawn into textures are invisible to search engines and screen readers.
  2. Content that only appears after JavaScript runs. Google does render JavaScript, but rendering happens in a queue, "once Google's resources allow". Google still calls server-side or pre-rendering "a great idea", partly because not all bots run JavaScript.
  3. Links that aren't links. Google states it "can only discover your links if they are <a> HTML elements with an href attribute". A click handler on a 3D object is not a link.
  4. One URL for many states. If every product color or apartment opens inside the same canvas with no URL change, Google sees one page.

The HTML-first rule for Three.js SEO

Build the page as if the 3D never loads. Then add it on top.

Diagram of a 3D loading strategy: HTML content and poster load first and are crawlable, the 3D bundle loads after first paint
HTML and poster first, 3D after first paint. Everything Google needs is in the first layer.

In practice the hero markup looks like this:

<section class="hero">
  <h1>Ridge 40 trail shoe</h1>
  <p>Carbon plate, three colorways, built for long descents.</p>
  <a href="/shop/ridge-40">Shop the Ridge 40</a>

  <div class="hero-3d" aria-hidden="true" style="aspect-ratio:16/9">
    <img src="/img/ridge-40-poster.webp" alt="" width="1600" height="900">
    <canvas></canvas>
  </div>
</section>

The H1, copy and link are real HTML. The 3D container is marked aria-hidden because it's visual, and the poster holds the space so the layout doesn't jump when the canvas mounts. If any copy exists only inside the 3D experience, Utsubo recommends a <noscript> fallback with the same headline, summary and CTA.

3D website SEO checklist

Item What to do How to check
Rendering Server-render or pre-render every route (Next.js, Astro and similar) View source: is the H1 there?
URLs per state One indexable URL per meaningful state, e.g. /product/x-pro?color=black Each state loads directly from a fresh tab
Links Real <a href> for every navigation; History API, not # fragments Crawl with any SEO crawler
Meta Unique title, description, Open Graph image per URL Paste URL into a social preview tool
Structured data Organization, Product, FAQPage as JSON-LD, matching visible content Rich Results Test
Alt text Descriptive alt on posters and meaningful images Accessibility audit
Speed LCP ≤ 2.5 s, INP ≤ 200 ms, CLS ≤ 0.1 (web.dev) PageSpeed Insights, field data

The URL-per-state rule matters most for configurators and real-estate sites. On an example residential project we built in Tallinn, where you hover lit windows to see each apartment, the production build would give every apartment its own server-rendered page with rooms, area, price and status in plain HTML. The facade is how people browse. The pages are what Google indexes.

Structured data deserves a note. Utsubo calls FAQPage schema "the single biggest GEO lever in 2026", GEO meaning visibility in AI search answers. That's their view, not a Google statement, but answering real questions in visible HTML is good practice either way.

Speed is part of SEO too; our 3D website performance guide covers the budget and loading order.

Check it with Search Console URL Inspection

Don't trust that it works; look at what Google sees.

  1. Open Search Console, paste the URL into URL Inspection.
  2. Click Test live URL. Google fetches the page in real time.
  3. Click View tested page. The HTML tab shows the rendered markup: search it for your H1, key copy and links.
  4. Open Screenshot to see how Google's renderer drew the page. A screenshot appears only for a successful live test.
  5. Check More info for JavaScript console errors and blocked resources, such as a model or script disallowed in robots.txt.
  6. If everything is there, Request indexing. It queues the URL but, per Google, doesn't guarantee it'll be indexed; a sitemap is better for many pages.

If the HTML tab shows a loading spinner and nothing else, you've found your problem.

Mistakes we see on 3D sites

  • A loading screen as the only content. "Loading 0%" is not a great page title.
  • Route changes without URL changes. Lovely transitions, one indexable page.
  • Text baked into GLB models. Keep type in HTML, layered over the canvas with CSS.
  • Hiding all content until a camera move finishes. Content can animate in, but it should exist in the DOM from the start.

Most of these also apply to motion-heavy sites without 3D; see animated website SEO. And if you're still choosing a stack, our guide to how a Three.js website is built explains where server rendering fits.

Questions people ask

Sources

LET’S OPEN A NEW TAB

What are you
thinking?

What’s on your mind?

This prepares an email to lab@asfari.studio. You review and send it from your email app.