Skip to content

feat(site): add sitemap, robots.txt, llms.txt and page metadata - #77

Merged
spetz merged 5 commits into
apache:mainfrom
justinmclean:agent-discoverability
Sep 3, 2026
Merged

feat(site): add sitemap, robots.txt, llms.txt and page metadata#77
spetz merged 5 commits into
apache:mainfrom
justinmclean:agent-discoverability

Conversation

@justinmclean

Copy link
Copy Markdown
Member

/sitemap.xml, /robots.txt and /llms.txt all returned 404, and the only metadata in the tree was a title, a description and a favicon.

  • sitemap.ts — 109 URLs: all docs pages, published posts, and the hand-written routes. Those are listed in src/lib/site.ts; a static export has nothing to discover them from, so a new page under (site)/ needs adding there.
  • robots.ts — allow all, pointing at the sitemap.
  • llms.txt/route.ts — an llms.txt index built with fumadocs-core's llms() helper, so it tracks meta.json instead of duplicating it. It says plainly that Iggy is a server and there's no API on this domain to call, which is what tools currently get wrong about us.
  • layout.tsxmetadataBase, per-route canonical, Open Graph and Twitter cards, and Organization / WebSite / SoftwareApplication JSON-LD.
  • not-found.tsx — recovery links. We already return a real 404; it just had nowhere to go but /docs.
  • (home)/page.tsx — the "How it works" steps were h4 under an h2, skipping a level. Now h3; nothing moves visually.

Tested with npm run build: checked the three new files, the canonical/og:*/JSON-LD in out/index.html, and the links in out/404.html.

Nothing on the site enumerated its own pages: /sitemap.xml, /robots.txt and
/llms.txt all returned 404. This adds all three, generated from the same
Fumadocs source the site already builds from, plus the metadata that search
engines and agents read first.

- src/app/sitemap.ts: every docs page, blog post and hand-written route
- src/app/robots.ts: allow all, pointing at the sitemap
- src/app/llms.txt/route.ts: an llmstxt.org index built with fumadocs-core's
  llms helper, prefaced by a short section on what the site is for
- src/app/layout.tsx: metadataBase, per-route canonical, Open Graph and Twitter
  cards, and Organization/WebSite/SoftwareApplication JSON-LD
- src/app/not-found.tsx: recovery links, so a 404 is not a dead end
- src/app/(home)/page.tsx: the "How it works" steps were h4 under an h2, so the
  heading hierarchy skipped a level

New routes outside docs and blog need adding to STATIC_ROUTES in src/lib/site.ts
to appear in the sitemap.
… title

Follow-ups found by reading the first build's output:

- blog posts canonicalised to a URL without the trailing slash the site
  actually serves, because the inherited relative canonical loses it on a
  catch-all route; set it explicitly instead
- the home page title already began with "Apache Iggy", so the root template
  appended the brand a second time
- llms.txt carried site-relative links and a second H1; links are now absolute
  and the generated index sits under an H2
- dropped the ASF postal address from the Organization JSON-LD: it was there
  only to satisfy an external scorecard, and the site does not otherwise
  publish it
JSON.stringify does not escape "<", so a value containing "</script>" would
close the tag early. Every value in the payload is a constant today, but the
escape makes that independent of what the object later carries.
kparisa added a commit that referenced this pull request Sep 3, 2026
> Stacked on #77 as it edits `llms.txt`, so it needs that one merged
first.

An agent that wants a docs page has to parse the rendered HTML today.
This writes a Markdown copy next to each page at build time, so
`/docs/server/security/` is also available as
`/docs/server/security.md`.

- `scripts/generate-docs-markdown.mjs` runs in `prebuild` after the
stars fetch and rewrites the copies from `content/docs` on every build.
Generated files are gitignored, like `src/github-stars.json`, so they
can't drift from the source.
- Each docs page advertises its copy with `<link rel="alternate"
type="text/markdown">`, and `llms.txt` states the convention.
- The `.md` files aren't in the sitemap. They're page alternates, not
pages.

`npm run build`, then: 76 `.md` files in `out/`, the `rel="alternate"`
and `rel="canonical"` links both present on a docs page, `index.html`
count unchanged, and `git status` clean.

---------

Co-authored-by: Kranti Parisa <kranti@laserdata.com>
kparisa
kparisa previously approved these changes Sep 3, 2026
@kparisa
kparisa self-requested a review September 3, 2026 07:08

@kparisa kparisa left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good

@spetz
spetz merged commit 0d0db59 into apache:main Sep 3, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants