From e4644f38217463872b245ff6bead198f7746a187 Mon Sep 17 00:00:00 2001 From: Devin Michael Date: Tue, 18 Aug 2026 12:40:08 +0700 Subject: [PATCH 1/3] Add llms.txt route generating a docs index at build time Serves /llms.txt on the static export, generated from the Fumadocs source via fumadocs-core's llms helper: full docs tree with per-page one-line descriptions, absolute URLs, and a single-H1 header that points agents at the developers portal and changelog. Closes #28 Co-Authored-By: Claude Fable 5 --- app/llms.txt/route.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 app/llms.txt/route.ts diff --git a/app/llms.txt/route.ts b/app/llms.txt/route.ts new file mode 100644 index 0000000..4d7974f --- /dev/null +++ b/app/llms.txt/route.ts @@ -0,0 +1,31 @@ +import { source } from '@/lib/source'; +import { llms } from 'fumadocs-core/source/llms'; + +export const dynamic = 'force-static'; + +const BASE_URL = 'https://docs.nextcommerce.com'; + +const generator = llms(source); + +export function GET() { + const body = [ + '# Next Commerce Merchant Documentation', + '', + '> Merchant documentation for Next Commerce (NEXT), an ecommerce platform for direct-to-consumer brands and performance marketers — storefronts, orders, subscriptions, payments, fulfillment, apps, and analytics.', + '', + 'Related resources: [Developer Docs](https://developers.nextcommerce.com/) (APIs, themes, campaigns), [Platform Changelog](/changelog), [nextcommerce.com](https://nextcommerce.com) (product and pricing).', + '', + generator.index(), + '', + ] + .join('\n') + // The generator emits site-relative links; agents fetch this file standalone, + // so links must resolve without a base URL. + .replaceAll('](/', `](${BASE_URL}/`) + // llms.txt expects a single H1; demote the generator's root heading. + .replace(/^# Docs$/m, '## Docs'); + + return new Response(body, { + headers: { 'Content-Type': 'text/plain; charset=utf-8' }, + }); +} From b7e2427fd238fbddeea47f57efc0fc1cf1f18d03 Mon Sep 17 00:00:00 2001 From: Devin Michael Date: Tue, 18 Aug 2026 13:04:37 +0700 Subject: [PATCH 2/3] Address review: config-owned base URL, positional H1 demotion, scoped URL rewrite - Canonical origin moves to siteConfig.url (single place, matches wrangler.jsonc) and the hand-authored changelog link uses it directly instead of relying on the post-processing. - The generator's root heading is demoted by position (first H1 line) rather than by the literal text '# Docs', so a Fumadocs title change can't silently ship two H1s. - The absolute-URL rewrite is scoped to the generated index only; the shared loader keeps relative URLs for the app's own routing, which is why the transform lives here rather than in a loader URL formatter. Co-Authored-By: Claude Fable 5 --- app/llms.txt/route.ts | 25 ++++++++++++++----------- lib/config.ts | 3 +++ 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/app/llms.txt/route.ts b/app/llms.txt/route.ts index 4d7974f..761ae00 100644 --- a/app/llms.txt/route.ts +++ b/app/llms.txt/route.ts @@ -1,29 +1,32 @@ import { source } from '@/lib/source'; +import { siteConfig } from '@/lib/config'; import { llms } from 'fumadocs-core/source/llms'; export const dynamic = 'force-static'; -const BASE_URL = 'https://docs.nextcommerce.com'; - const generator = llms(source); export function GET() { + const index = generator + .index() + // The shared loader must keep site-relative URLs for the app's own routing, + // so the generated index is absolutized here instead — agents fetch this + // file standalone, with no base URL to resolve against. + .replaceAll('](/', `](${siteConfig.url}/`) + // llms.txt expects a single H1 (ours, below); demote the generator's root + // heading by position rather than by literal text. + .replace(/^# /m, '## '); + const body = [ '# Next Commerce Merchant Documentation', '', '> Merchant documentation for Next Commerce (NEXT), an ecommerce platform for direct-to-consumer brands and performance marketers — storefronts, orders, subscriptions, payments, fulfillment, apps, and analytics.', '', - 'Related resources: [Developer Docs](https://developers.nextcommerce.com/) (APIs, themes, campaigns), [Platform Changelog](/changelog), [nextcommerce.com](https://nextcommerce.com) (product and pricing).', + `Related resources: [Developer Docs](https://developers.nextcommerce.com/) (APIs, themes, campaigns), [Platform Changelog](${siteConfig.url}/changelog), [nextcommerce.com](https://nextcommerce.com) (product and pricing).`, '', - generator.index(), + index, '', - ] - .join('\n') - // The generator emits site-relative links; agents fetch this file standalone, - // so links must resolve without a base URL. - .replaceAll('](/', `](${BASE_URL}/`) - // llms.txt expects a single H1; demote the generator's root heading. - .replace(/^# Docs$/m, '## Docs'); + ].join('\n'); return new Response(body, { headers: { 'Content-Type': 'text/plain; charset=utf-8' }, diff --git a/lib/config.ts b/lib/config.ts index c666225..c930d8e 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -1,5 +1,8 @@ export const siteConfig = { companyName: 'Next Commerce', + // Canonical origin for absolute links in machine-readable outputs (llms.txt). + // Must match the route in wrangler.jsonc. + url: 'https://docs.nextcommerce.com', githubOrg: 'NextCommerceCo', githubRepo: 'docs', get githubUrl() { From 2e7620b47160fd3fd9baa3abddb116a410918973 Mon Sep 17 00:00:00 2001 From: Devin Michael Date: Tue, 18 Aug 2026 13:08:06 +0700 Subject: [PATCH 3/3] Document the no-trailing-slash invariant on siteConfig.url Co-Authored-By: Claude Fable 5 --- lib/config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/config.ts b/lib/config.ts index c930d8e..1f05ced 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -1,7 +1,8 @@ export const siteConfig = { companyName: 'Next Commerce', // Canonical origin for absolute links in machine-readable outputs (llms.txt). - // Must match the route in wrangler.jsonc. + // Must match the route in wrangler.jsonc. No trailing slash — consumers + // concatenate `/${path}` onto this value. url: 'https://docs.nextcommerce.com', githubOrg: 'NextCommerceCo', githubRepo: 'docs',