Fix AI visibility / Framer

Why AI crawlers can't read your Framer site

A published Framer site is pre-rendered to static HTML and is usually readable without JavaScript, so when ChatGPT misses your content the cause is specific: a code component, an embed, or an interaction that keeps text out of the HTML.

Framer serves your site as pre-rendered static HTML from a CDN, so unlike a plain React single-page app, a Framer page usually reaches ChatGPT's crawlers with its native text already in place. If a scan shows your content missing, the cause is almost always one specific choice, not the platform itself.

This guide covers the ways a Framer page can hand a crawler less than a visitor sees, how to check which one is happening, and the exact change for each. It ends with how to verify the fix with a Lantad scan.

How Framer renders

When you publish in Framer, each page is pre-rendered to static HTML and served from a CDN, so the headings, body text, and CMS content you placed on the canvas are usually present in the raw HTML a no-JavaScript crawler receives. That is the common case, and it is why most Framer sites read fine. Content goes missing in three situations. First, a code component or custom code override that reads window, document, or navigator during render cannot run on the server, so Framer hides that component during the server render and retries it in the browser after load. Any text inside that component is absent from the served HTML and is built by JavaScript the crawler does not run. This is scoped to the affected component, not the whole page, so your other native text still renders into the HTML. Second, a third-party embed such as a form, a booking widget, or a chat tool loaded by script or iframe is fetched after load, so its content is never in the served HTML. Third, content that only appears after a user action, such as a tab, an accordion, a modal, or a "load more" control that injects items on click, may not be in the initial HTML at all. Appear-on-scroll animations are safe, because the text is already in the HTML and only its opacity changes.

The fix

  1. Keep primary text as native content, not a code component

    Framer pre-renders text layers and CMS fields into the served HTML, so keep your headlines, body copy, and the actual answers a reader wants as native Framer elements or CMS content. Avoid putting meaningful text inside a code component that fetches or builds it at runtime, because that text depends on JavaScript the crawler will not run.

  2. Guard browser APIs so code components stay in the server HTML

    When a code component or override reads window, document, or navigator during the render pass, that API does not exist on the server, so Framer hides the component during the server render and remounts it in the browser after load. Any text inside it is then missing from the static HTML. Guard those calls so they run only after mount, for example behind a typeof window !== 'undefined' check or inside a useEffect, so the component renders on the server and its text lands in the served HTML. This affects only the component, not the rest of the page, but if that component holds primary copy the gap can be large.

  3. Do not hide important content behind an interaction or embed

    Anything a crawler should read has to be in the initial HTML, not injected when someone clicks a tab, opens an accordion, or after a third-party script loads. Move the important text into the page body. If you rely on a Framer accordion or tab for key content, keep the collapsed content in the DOM rather than removing it, and for a critical embedded tool like a form or booking widget, add the key details or a plain-text summary as native Framer text alongside the embed so the substance is in the HTML.

  4. Set the Framer SEO basics and JSON-LD

    In page settings, fill the title and description, keep a single H1 with headings in order, and add schema.org JSON-LD through custom code (Site Settings or Page Settings, End of head) so it lands in the served HTML rather than being added later by script. Framer adds no structured data on its own, so this is manual. Framer regenerates sitemap.xml on publish, so confirm the page is included and is not set to hidden or excluded from indexing.

  5. Verify with a Lantad scan

    Scan the published URL with Lantad. It fetches the page once as LantadBot with no JavaScript and once in a full browser, then diffs them. Prose Parity near 100 means the crawler sees what visitors see, and any gap is the exact text missing from the HTML. Access checks robots.txt and the server response per named crawler such as GPTBot, and Structure and Schema flag heading and JSON-LD issues. Re-scan after each change to confirm the gap closed.

Common questions

Are Framer sites readable by ChatGPT by default?
Usually yes. Framer pre-renders each published page to static HTML, so native text and CMS content are in the HTML a no-JavaScript crawler receives. The exceptions are specific: a code component hidden on the server because it touched a browser API, third-party embeds loaded by script, and content that only appears after an interaction. Being readable is a prerequisite for being cited, never a guarantee of it.
Why does my Framer page look full in a browser but empty in a scan?
Your browser runs the JavaScript that builds the page, while an AI crawler reads the raw HTML your server returns. Framer pre-renders your native text into that HTML, but a code component that touches window or document during render is hidden on the server and mounted only in the browser, so its text is absent from what the crawler receives. The same happens with content inside a script-loaded embed or revealed only after a tab or accordion. Lantad's Prose Parity check shows exactly how much of the visible text is missing from the HTML.
Does Framer's static rendering mean I do not need to do anything?
Static rendering covers native text and CMS content automatically, which handles most pages. It does not cover text inside a code component that was hidden on the server, content injected by a third-party embed, or sections revealed only on interaction. Those can still be absent from the HTML, so scan the page to confirm what a crawler actually receives rather than assuming.

See what AI reads on your Framer site

Run a free scan: paste a URL and see exactly what AI crawlers can and cannot read, with a graded report and ranked fixes.