Checking it worked
Geoffy does not take your word for it. After you publish, we fetch your live product page and look for our markup in the server-rendered HTML. A product stays pending until we find it, and your dashboard count only ever shows products confirmed on your real site.
If a product stays pending
| Reason | What it means | What to fix |
|---|---|---|
code_not_added | We fetched the page and our markup was not in it | The component is not on the page, or it is rendering on the client |
stale_version | Our markup is there, but it is an older copy | Nothing. Your cache clears itself within the revalidate window (one hour by default) |
canonical_broken | The page does not name itself as canonical | See "Before you start": most often a missing per-page metadata export |
You can check the same thing yourself:
curl -s https://yourdomain.com/en/products/your-handle | grep -c 'data-geoffy'A number greater than zero means it is in the server-rendered HTML, which is what matters. The same command works against your dev server while you are building; swap the host.
And the namespace
Geoffy checks the /apps/geoffy mount the same way: by fetching it, not by
trusting the setting. Check it yourself with:
curl -si https://yourdomain.com/apps/geoffy/sitemap.xml | head -20 A 200 is not the check. That is the one thing worth knowing
here, because it is what makes a broken mount look fine: a catch-all route in your app
answers every path (including this one) with your home page and a perfectly
healthy 200.
So Geoffy checks three things instead, and you can check the same three by eye:
| Check | Why |
|---|---|
| The response is genuinely proxied from Geoffy | Not your home page, not a CDN interstitial. If what comes back looks like your own site, a catch-all route is winning and the namespace route is not being reached |
| It is your site's content |
A GEOFFY_SITE_KEY copied from another project would otherwise confirm
a mount that is serving someone else's catalogue under your domain
|
content-type is application/xml or text/xml | A sitemap served as HTML is one a crawler will not parse |
If the mount is not confirmed, the dashboard says which of these it is:
| Reason | What it means |
|---|---|
not_mounted | The path answered, but not with our bytes. Usually a catch-all route serving your home page, or the route file is not deployed yet |
wrong_site |
Our marker came back carrying a different site key. Your
GEOFFY_SITE_KEY belongs to another Geoffy site
|
unreachable | We could not fetch it at all. This is not the same as "not mounted" and is not recorded as a failure. We try again |
While the mount is unconfirmed, your llms.txt simply says less: it omits
the product twins and the Geoffy sitemap rather than pointing a crawler at URLs that
answer with your home page.
What a local run cannot do
Geoffy confirms your integration by fetching your live product page at
its canonical URL (the public one, not your machine). So until the integration is
deployed, products stay pending with code_not_added no matter how correct
everything looks locally.
That is the check working as intended: it reports what your visitors and the crawlers
actually get. Prove it locally with the curl above, ship, and let the
confirmation follow.
Astro specifics
Section titled “Astro specifics”code_not_added on a page you are sure is correct is almost always one of two things:
getGeoffyProductMarkupreturnednulland your guards rendered nothing. That is the helper working as designed: it returnsnullwhen Geoffy has nothing published for the handle, when Geoffy is unreachable, and whencanonicalUrldoes not match the page Geoffy published against. There is nodata-geoffy-skippedmarker on this side to tell those apart, so check the handle first.- The page was prerendered before you published. On a static build the markup is baked in at build time. Publishing afterwards changes nothing until you rebuild; see how updates arrive.
If the namespace check reports not_mounted on a site you believe is server-rendered,
confirm export const prerender = false is actually in the route file. A prerendered
[...path].ts fails the build outright, but a route that was never deployed simply
answers 404.