Skip to content

The Geoffy namespace

Geoffy has more surfaces than the three root files: a plain-text twin for every product, a sitemap of them, and your buying-guide pages. They all live under one namespace, and this single catch-all route puts the whole of it on your domain.

app/apps/geoffy/[...path]/route.ts
import { createGeoffyProxyRoute } from "@geoffy/headless/next";
export const GET = createGeoffyProxyRoute({ siteKey: process.env.GEOFFY_SITE_KEY! });

That is it. You now serve:

  • Directoryapps/
    • Directorygeoffy/
      • Directoryllm/
        • {page path}.md each page, as plain text, at its own path (no commerce platform)
        • {handle}.md each product, as plain text (Shopify behind your storefront)
      • Directoryguides/
        • {slug} each published buying guide
        • {slug}.md the same guide, as plain text
      • sitemap.xml all of the above, listed

Without it, that content is still served, but from api.geoffy.ai, not from you.

An AI system that reads your buying guide there records api.geoffy.ai as the source, so the citation your guide earns goes to us instead of to you. The point of the route is that everything about your products is addressed at your own domain.

Why a namespace and not three more helpers

Section titled “Why a namespace and not three more helpers”

It is the last integration change this package will ask you for. Anything Geoffy adds later appears under the namespace you have already mounted: no upgrade, no new file, no re-deploy on your side.

apps and geoffy are ordinary static route segments, so this wins against a catch-all such as app/[lang] with no configuration. That is the reverse of the rewrite problem in the site-wide files: rewrites lose that race, route segments win it.

createGeoffyProxyRoute({ siteKey, revalidateSeconds: 3600 });

They show up in your own logs, so it is worth knowing they are deliberate.

  • If Geoffy is unreachable or erroring, this route answers 503 with a Retry-After, never a fabricated 404, so a crawler retries instead of dropping the page from its index.
  • Query strings are not forwarded, because no artifact reads one.
  • It tells Geoffy which AI agent asked for a file, by the agent's name (GPTBot). A browser's user agent is never passed on. That is how Geoffy can show you which agents read your product text versions and guides, even without AI visit tracking.
  • Each plain-text twin names its HTML page as canonical. A product or page twin under llm/, or a guides/{slug}.md twin, carries Link: <https://…>; rel="canonical". It names your product page, or the buying guide, on your domain. A search engine that indexes the twin then gives the credit to that page. This needs 0.3.3 or later.
  • Geoffy's X-Robots-Tag is kept. When Geoffy marks a response noindex, nofollow or none, the route keeps that header on a 200 and on a 404. No other header from Geoffy is copied, and a value in an unexpected shape is dropped. This needs 0.3.3 or later.
  • A moved buying guide answers 301. When a guide gets a new address, its old address answers 301 with a Location under /apps/geoffy/ on your domain, never one on Geoffy's domain.

Geoffy notices and simply says less: your llms.txt will not advertise the twins or the sitemap, rather than pointing a crawler at pages that are not there. Nothing breaks; you get less. Confirming the mount is covered in checking it worked.