Skip to content
Base44 SEO Journal

What Googlebot and AI crawlers actually get from Base44 apps

We fetched 186 pages from 47 Base44 sites as Googlebot, GPTBot and a browser. Crawlers get cached renders or a hidden summary: a different page, late, and not on every page.

14 min read

Base44’s crawler pre-rendering is bad for SEO in three ways. Crawlers are served a different page from the one visitors see, which puts sites in cloaking territory by Google’s own definitions. The real content reaches crawlers late, often only on a later crawl. And many pages never get rendered at all. We fetched 186 pages from 47 live Base44 sites: a first Googlebot request got the real page on only 34% of inner pages, 31% of inner pages still had no render minutes later, and a day later 13 of 44 pages that had been rendered were back to the auto-written summary.

This post covers what Base44 sends, to which crawlers, and what that means for indexing. If you want the practical fixes first, the Base44 SEO guide turns these findings into a checklist.

The short version

  • Every Base44 page ships a hidden block called seo-snapshot: a heading built from the page and app name, an auto-written description of the app, and a list of your pages. Browsers get it too, and React swaps it out when the app loads.
  • Base44 serves recognized crawlers a cached render if it has one and the snapshot if it doesn’t, a page visitors never see. Nothing is rendered while the crawler waits, and requesting a page doesn’t reliably get it rendered.
  • Renders don’t stay put. About a day later, 13 of 44 pages that had a render served the snapshot again.
  • On a first Googlebot request, 23 of 47 homepages (49%) and 47 of 139 inner pages (34%) came back rendered. A few minutes later, 30 homepages and 79 inner pages had renders. 43 inner pages were still snapshot-only.
  • Google’s inspection tool, Brave’s crawler, Meta’s AI crawler, Amazon’s, Common Crawl and every SEO audit tool we tried only ever got the snapshot.
  • Sitemaps listed 672 URLs across the 47 sites. None pointed at an individual record, and 21% were login, password-reset, admin or checkout pages.

How we ran the test

We needed live Base44 sites on custom domains, since that’s where Base44’s SEO features apply. Base44’s docs say its SEO setup “is designed and supported for apps that are published on a custom domain.”

  1. Sample. We took all 98 apps listed in the current week of Base44’s Launchpad, the community showcase, and fetched each at its base44.app address. 96 responded.
  2. Custom domains. Base44 writes WebSite and Organization structured data into each app’s HTML, including the app’s public URL. That gave us 57 custom domains. 47 were live and served by Base44 (every Base44 response carries an x-render-origin-server: uvicorn header).
  3. Pages. For each of the 47 sites we fetched the homepage plus up to three inner pages picked at random from the site’s own sitemap.xml, skipping login and account pages. That’s 186 pages.
  4. User agents. Each page was requested three times in a row: as desktop Chrome, as Googlebot and as GPTBot. We repeated the whole run a few minutes later.
  5. Classification. If the HTML contained Base44’s seo-snapshot block, we counted it as a snapshot. If it contained the app’s real rendered markup instead, we counted it as a render.

The test ran on 23 September 2026. The limits of that design are listed at the end.

What Base44 puts in every page: the seo-snapshot block

Open View Source on any Base44 page and you’ll find this inside the root div, before React has run:

<div id="root">
  <div data-seo-source="builder" id="seo-snapshot"
       style="position:absolute;width:1px;height:1px;padding:0;margin:-1px;
              overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;">
    <main>
      <header>
        <h1>findgestor.com</h1>
        <p>findgestor.com manages 3 data types including gestors. Helps you organize,
           track, and share your work in 1 place for teams and solo users.</p>
      </header>
      <nav aria-label="Pages">
        <h2>Pages</h2>
        <ul>
          <li><a href="/SubmitGestor">Submit Gestor</a> ... Submit Gestor on findgestor.com. ...</li>
          <li><a href="/About">About</a> ... About on findgestor.com. ...</li>
          ...

That’s a real example, trimmed, from one of the sites in the sample. It matches what Base44’s documentation describes as a fallback: “a structured snapshot carrying that page’s heading, its description, and links to your other pages, so crawlers always receive meaningful content rather than an empty shell.” Base44’s changelog entry for 10 June 2026 added “clearly labeled page sections and a description for each page” to it.

Three things stand out.

  • It’s a template, filled from the page name and your app description. On the homepage the H1 is the app name. On an inner page it’s the page name plus the app name (“About | findgestor.com”), followed by a sentence like “About on findgestor.com.” and the app description again, sometimes cut off mid-word. Then comes the same list of every page in the app. None of it is the page’s own heading or copy.
  • The description is written by Base44, and it reads like it. “Manages 3 data types including gestors. Helps you organize, track, and share your work in 1 place” is the snapshot’s summary of a directory of Spanish tax advisers. The real homepage, which Googlebot got once a render existed, opened with “Find your gestor in Spain” and 12,965 characters of actual content.
  • It’s hidden with the standard screen-reader clipping pattern. People never see it because React replaces the contents of root on load. Crawlers that don’t run JavaScript read it as the page.

Base44 presents this as a safety net. In practice it’s a second, hidden page that crawlers get in place of yours, and the next section shows how often that happens.

Most first requests get the snapshot

Here’s what came back for the Googlebot user agent on the first pass and on the second pass a few minutes later.

PagesRendered, first requestRendered, second passStill snapshot only
Homepages4723 (49%)30 (64%)16
Inner pages13947 (34%)79 (57%)43 (31%)

Between the two passes, 32 inner pages and 7 homepages switched from snapshot to render, so Base44 does fill its cache in the background. As the next section shows, our requests weren’t what filled it.

GPTBot got 29 rendered homepages on the first pass to Googlebot’s 23, with each of its requests a second or two after Googlebot’s. On the second pass the two matched. Base44 serves every recognized crawler the same cached copy, so the difference points to pages being added to the cache while we tested.

Renders also expire. We re-requested 60 of the pages about a day later. Of the 44 that had a render the day before, 13 served the snapshot again, and 14 pages that never had a render still didn’t.

Of the 79 rendered inner pages, 17 were thin: forgot-password screens and in-app views such as a restaurant order board. Those are real renders of pages with little text, and they’re in the sitemap, which is its own problem (see below).

Base44 serves renders from a cache, and requests don’t fill it

Rendered responses came back in about 0.3 to 1 second. No headless browser renders a React app that fast, so every render a crawler gets is a stored copy. We tested how that cache behaves the next day:

  • Rendered pages stayed rendered. Twelve pages with a render returned it on all 8 of 8 rapid repeat requests.
  • A fresh URL never got rendered. Adding a made-up parameter such as ?b44check=123 to those same pages created a new cache entry. It returned the snapshot on 13 straight requests over three minutes.
  • Tracking parameters share the cache. The same pages with ?utm_source=... returned the render at once, since Base44 ignores tracking parameters, as its canonical tags do.
  • Asking didn’t help. We requested all 28 pages that were serving the snapshot every 10 seconds for four minutes with Googlebot’s user agent. None got a render.

So a crawler gets whatever the cache holds at that moment. What fills it, and when, isn’t visible from outside. Base44’s docs say it “refreshes this rendered content when you publish,” which is the only trigger it documents.

Which crawlers Base44 renders for

To see which user agents Base44 treats as crawlers, we took pages where a render was already in place and requested them with 33 different user-agent strings. The split below held on every page but one, which served its rendered version to every visitor, browsers included.

Gets the rendered pageGets only the snapshot
Googlebot (desktop and smartphone)Google-InspectionTool
BingbotGoogleOther
GPTBot, OAI-SearchBot, ChatGPT-UserBravebot
ClaudeBot, Claude-UserMeta-ExternalAgent
PerplexityBot, Perplexity-UserAmazonbot
Applebot, DuckDuckBot, YandexBotCCBot (Common Crawl)
facebookexternalhit, Twitterbot, LinkedInBotBytespider
Slackbot, Discordbot, WhatsAppMistralAI-User
AhrefsBot, SemrushBot, Screaming Frog, curl

The left column covers what matters most for ranking: Google, Bing, and the fetchers behind ChatGPT, Claude and Perplexity answers. The right column has three entries worth your attention.

Google-InspectionTool is the user agent behind Search Console’s Test live URL button and Google’s Rich Results Test. On Base44 it always got the snapshot, including on pages where Googlebot’s user agent got the full render. So the live test shows you something different from what Googlebot is served. The indexed version under View crawled page is the one to trust. The Search Console guide walks through reading it.

Bravebot feeds Brave Search, an independent index that other products license for web results. If you care about Brave, your Base44 pages reach it as summaries.

Meta-ExternalAgent is Meta’s crawler for its AI products. Meta’s link-preview fetcher, facebookexternalhit, did get renders.

The SEO tools in the right column explain why a Screaming Frog or Ahrefs crawl of a Base44 site reports every page with the same H1 and a near-identical body. That’s the snapshot. It isn’t what Googlebot gets once a render exists, so don’t make decisions from those crawls without knowing that.

Base44 decides by user agent, so you can test it yourself

Every result above came from changing the user-agent string on an ordinary request from an ordinary IP address. Base44 served the render in response to that string alone, so it decides by user agent. That makes this one of the rare platforms where you can check what a crawler gets with a single command:

UA='Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
curl -s -A "$UA" https://yourdomain.com/your-page | grep -c 'id="seo-snapshot"'

1 means the request got the generated summary. 0 means it got your rendered page. Because every recognized crawler gets the same cached copy, this one request tells you what Googlebot, Bingbot and GPTBot are getting right now. What you can’t learn from outside is when Base44 will render a page that’s serving the summary, or how long a render stays cached.

What’s in a Base44 sitemap, and what isn’t

Every one of the 47 sites served a valid sitemap.xml, and 46 served llms.txt as well. Their contents are thinner than the files suggest.

  • Sizes were small: 4 to 40 URLs, around a dozen for a typical site. The sitemap lists your pages (one entry per page file in the app) and nothing else.
  • No records. Across 672 sitemap URLs, zero pointed at an individual product, post, listing or profile. If your app shows records at URLs like /BlogPost?id=... or /series/<id>, those pages aren’t in the sitemap.
  • Login and utility pages are in. 143 of the 672 URLs (21%) were pages like /forgot-password, /reset-password, /login, /admin or /checkout, and 35 of the 47 sites had at least one. Base44 excludes pages that require a login, but a password-reset form doesn’t require a login, so it goes in.

Base44’s docs offer three fixes: a per-page indexing toggle, a replacement public/sitemap.xml, or a sitemap served from a backend function. The Base44 sitemap guide covers all three.

Record pages: the content can render, the titles don’t

This part was a spot check, since most Launchpad apps aren’t content sites. We found record-style links on the rendered pages of five sites and fetched eight of them twice.

  • Two different match pages on a football prediction app (/Match?id=...) returned byte-for-byte identical snapshots on both passes, titled “Match | The Big Ball Game”. To a crawler, every match on that site is the same page.
  • A series page on a reading app (/series/<id>) rendered, and the render included the series’ real name and description. Its title was still “Series | StoryNook” with no meta description. Every series on the site shares that title.

That second case is the pattern to expect. Base44 generates titles from the page’s URL (“for pages without URL parameters”), so a template page that shows many records gets one title for all of them. Rendering solves the body. The title, description and sitemap entry for each record are still yours to fix. We cover options in the meta tags guide.

Why this is bad for SEO

Crawlers get a different page from visitors

On a summary response, a recognized crawler gets a page heading, a stock description of your app and a list of links. A visitor gets your actual page. Google’s spam policies define cloaking as “presenting different content to users and search engines,” and give “inserting text or keywords into a page only when the user agent that is requesting the page is a search engine” as an example. Google’s dynamic rendering guidance only excuses serving crawlers a separate version “as long as your dynamic rendering produces similar content,” and warns that “serving completely different content to users and crawlers can be considered cloaking.”

The summary block is also hidden with a 1-pixel clip. Google’s hidden-text policy lists CSS tricks like that as spam, with one exception: text “intended to improve the experience for those using screen readers.” Screen readers never read Base44’s summary, because React replaces it before anyone uses the page. It exists for crawlers.

Nobody outside Google knows how it scores these pages. Serving crawlers a different, hidden page from the one visitors see is exactly the pattern its policies describe, and it’s a risk you carry on every page that hasn’t been rendered.

The real content arrives late

Raw response times were fine: median time to first byte was about 0.6 to 0.7 seconds for browsers, summaries and renders alike. That speed is the tell that nothing renders while a crawler waits. A crawler gets whatever the cache holds, so after you publish or change a page, crawlers see the summary or a stale render until Base44 gets around to rendering it, on a schedule you can’t see or control. If Google falls back to rendering your JavaScript itself, the page waits in its rendering queue, which is the delay pre-rendering exists to remove. Either way, new and updated content reaches the index later than it should.

Many pages never get covered

After two passes, 31% of inner pages had no render. A day later, 30% of the pages that had been rendered were back to the summary. Record pages never appear in the sitemap. Twelve crawlers and tools, including Google’s own inspection tool, Bravebot, Meta’s AI crawler and Common Crawl, never get a render at all. For each of those, your site is a set of near-identical summaries.

Everything else checked out

Some of the fundamentals were solid across the board:

  • Canonicals: all 47 custom-domain homepages carried a self-referencing canonical tag.
  • Meta descriptions: all 47 homepages had one. On 6 sites, the same description appeared on every sampled page.
  • Duplicate hosts: each of these apps also answers at its base44.app address. For 43 of 46 apps, that copy sent x-robots-tag: noindex, follow, which keeps the duplicate out of Google. Three didn’t, and two of those declared the base44.app address as canonical, so the same site competes with itself in the index.
  • Default titles: two of the free base44.app apps were still titled “Base44 APP”, the default, which is also how many Base44 apps show up in Google results.

What this means for your Base44 app

When Base44’s render does reach a crawler, it’s a real render with your data in it. Everything around it is the problem: a hidden, different page on first visits, content that reaches crawlers late, renders that expire, and records that never make it into the sitemap.

Requesting your own pages won’t fix it, as the cache test showed. Base44 gives you no way to render a page on demand, so the fixes all sit outside it. That matters most if your traffic depends on dynamically loaded content (product pages, directory listings, blog posts stored in your app’s data: anything that isn’t written into the page’s source code). You have two real options, plus monitoring:

  1. Monitor what crawlers get. Run the curl check above across your sitemap after each publish, so you know which pages are serving the summary. Republishing is the only refresh trigger Base44 documents.
  2. Put a pre-rendering service in front of your custom domain. It renders every URL ahead of time and serves the finished HTML to every crawler, including the ones Base44 skips. We’d use Encited here: it has a Base44 setup that proxies to your base44.app address, serves Markdown to AI agents, and keeps crawl logs showing which bot got what. Prerender.io and a self-hosted Puppeteer service are the alternatives.
  3. Export the app and move it to a framework with server rendering. The most work and the most control. The export guide covers what comes with you.

Limits of this test

  • The sample skews toward apps. Launchpad showcases apps built for people to use, so it has more login screens and fewer content pages than a typical business website built on Base44.
  • User-agent strings from ordinary addresses. We sent crawler user-agent strings from ordinary IP addresses. Base44 responded to the string, which is why the test works, but we can’t rule out that requests from Google’s own IP ranges are treated differently.
  • Two passes minutes apart, plus a re-check and cache tests a day later. We couldn’t see what fills Base44’s cache or how long a render stays in it.
  • Record pages were a spot check of eight URLs on five sites.

What to do next

  1. Run the curl check above on your five most important pages.
  2. Look at your sitemap.xml and turn off indexing for password-reset, login and admin pages from the SEO & GEO page’s Advanced Settings.
  3. Set a custom title and description for every page that matters, starting with template pages that show records.
  4. If most of your pages carry dynamically loaded content, decide between a pre-rendering service and exporting, using the Base44 SEO guide as the checklist.

Found something wrong or out of date? Base44 ships changes every week and we'd rather fix a guide than let it rot.

Disclosure: the team behind this guide also builds Encited, mentioned above.

Frequently asked questions

Is Base44's crawler pre-rendering cloaking?
It creates a real cloaking risk. When no render is ready, Base44 serves recognized crawlers a hidden, auto-written summary that differs from the page visitors see. Google says dynamic rendering isn't cloaking only as long as it produces similar content, and lists inserting text only when the requester is a search engine as a cloaking example.
Does Base44 pre-render pages for Google?
Only when it has a cached render. Base44 serves recognized crawlers a pre-rendered copy from a cache and never renders while the crawler waits. In our test of 47 live Base44 sites, a first Googlebot request got the rendered page on 34% of inner pages. The rest got an auto-written summary, and requesting them again didn't reliably produce a render.
What is the seo-snapshot div in Base44's HTML?
It's a visually hidden block Base44 injects into every page's HTML: a heading built from the page and app name, a generated description, and a list of the app's pages. Browsers receive it too, and React replaces it when the app loads. Crawlers get it whenever a full render isn't ready yet.
Which crawlers does Base44 recognize?
In our tests Googlebot, Bingbot, GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, PerplexityBot, Applebot, DuckDuckBot, YandexBot and the major link-preview bots got the rendered page once it existed. Google-InspectionTool, GoogleOther, Bravebot, Meta-ExternalAgent, Amazonbot, CCBot and SEO audit tools only ever got the summary.
Why does Search Console's live test show a different page than Googlebot gets?
The live test in URL Inspection fetches with Google-InspectionTool, and Base44 doesn't treat that user agent as a crawler to pre-render for. In our tests it always received the generated summary, even on pages where Googlebot's user agent received the full render.
Are record pages like /Product?id=123 pre-rendered on Base44?
Sometimes, and never in the sitemap. None of the 672 sitemap URLs across 47 sites pointed at an individual record. Where a record page did render, the content was there but the title was the generic page name, such as 'Series | StoryNook', shared by every record.

Read next