Markdown pages
View .mdMarkdown pages
Section titled “Markdown pages”Every page a Kismet site declares has a Markdown twin at the same URL plus
.md — the version an AI agent reads instead of rendering HTML. /llms.txt
links the twins, so a broken twin or a twin that links a page the site does
not serve is a dead end for every agent that followed the index. This guide
says which pages have twins, how the SDK builds them, how a site serves them,
and how to check the links inside them.
Which pages have a Markdown twin
Section titled “Which pages have a Markdown twin”The SDK’s page-type registry is the only list of page types, and every type
in it carries a Markdown composition. The twin is per declared page: a page
exists for an agent when the site declares it with
definePage and serves it.
| Page type | HTML route | Markdown twin |
|---|---|---|
| Homepage | / |
/index.md |
| Results (collection) | /properties/ |
/properties/index.md |
| Property | /properties/{slug} |
/properties/{slug}.md |
| Property group | /groups/{slug} |
/groups/{slug}.md |
| Group index | /groups/ |
/groups/index.md |
| Reviews | /properties/{slug}/reviews |
/properties/{slug}/reviews.md |
| Rates | /properties/{slug}/rates |
/properties/{slug}/rates.md |
| Blog index | /blog/ |
/blog/index.md |
| Blog post | /blog/{slug} |
/blog/{slug}.md |
| FAQ, About, Contact, Owners | /faq, /about, /contact, /owners |
same route + .md |
| Booking confirmation | /booking-confirmation |
/booking-confirmation.md |
| Custom | the site declares it | the declared URL + .md |
A page marked private never serves a twin — the twin endpoint returns 404,
the same boundary the HTML page enforces elsewhere. Unlisted-but-public pages
keep twins; only /llms.txt decides what is advertised.
How the SDK builds the twin
Section titled “How the SDK builds the twin”markdownForPage(page) renders the twin body, in this order:
- Your
renderMarkdownoverride, ifdefinePagegot one — it wins. - The page type’s composition — the property twin carries the details, the long description, highlights and selling points, amenities, neighborhood and location, the pricing summary, the photos, and a Book section linking the property page and the rates twin; the group twin lists its members.
- The fallback: title,
Canonical:line, description.
Every twin starts with a Canonical: line naming the HTML page it mirrors,
and the HTML page carries <link rel="alternate" type="text/markdown">
pointing back at the twin.
Wire the site
Section titled “Wire the site”The SDK builds the Markdown string; the site decides which URL serves it. Two supported shapes:
Next.js — rewrite .md to one twin route. Rewrite every declared page’s
.md URL to a single route that calls the page adapter’s markdown handler,
which resolves the page for the request URL and returns markdownForPage:
const nextConfig: NextConfig = { async rewrites() { return [ { source: "/properties/:slug", destination: "/property-page" }, { source: "/properties/:slug.md", destination: "/markdown-twin" }, { source: "/groups/:slug.md", destination: "/markdown-twin" }, ]; },};The markdown handler is exact-host and same-origin: a twin URL that names
no declared page returns 404, so a twin exists only where the HTML page does.
Static export — write the twins as files. After the build, write each
twin next to its HTML (the homepage twin at /index.md). The checker probes
<route>.md then <route>/index.md, and / twins at /index.md.
Either shape, the site also serves:
/llms.txtfromKismet.llmsTxt— it links every public twin. Pass{ markdownTwins: false }only if the site serves no twins at all; then thesite/markdown-twinrule does not require them.Accept: text/markdownnegotiation on the HTML routes, so an agent that asks for Markdown instead of HTML gets the twin body without the.mdURL.
What twins link
Section titled “What twins link”A twin links the pages its guest actions need, and every link must resolve on that site:
- The
Canonical:line points at the twin’s own HTML page. - A property twin links the rates twin (
…/rates.md) and the property page. - Group and index twins link their members.
/llms.txtlinks every public twin.
The rule is absolute: a twin may only link URLs the site actually serves.
The SDK builds links from the page type’s template; if the site does not
serve that page, the link is broken for agents. That exact failure shipped
on a live site — property twins linked /properties/<slug>/rates.md while
the site rewrote only property and group twins, so every rates link
returned 404 (KIS-21888). Serve the linked page, or remove the link, and
re-run the link check before go-live.
Check before go-live
Section titled “Check before go-live”-
Twin exists and is Markdown.
curlany declared page’s.mdURL and expect 200 with aCanonical:line:Terminal window curl -fsSL https://example.com/properties/<slug>.md | head -5 -
Every declared page has a twin. Run the conformance check in production mode — the
site/markdown-twinrule fails for each declared page-type route without a reachable twin:Terminal window npx kismet check https://example.com --env production --json -
Every link inside every twin returns 200 on the live domain — the curl loop is go-live checklist N7. The checker’s
site/internal-linksrule grades twin links it can read from a built directory; twins served through a rewrite need the live curl check, because no static file holds their body.