Add JSON-LD and llms.txt for AI search - #782
Conversation
One local plugin injects Organization and SoftwareSourceCode structured data using the same @id as swmansion.com, and writes llms.txt from the pages Docusaurus just built. CI fails if the file is missing or lists nothing.
A title containing regex metacharacters would change the pattern's meaning or throw at build time.
There was a problem hiding this comment.
Pull request overview
This PR adds SEO-oriented outputs to the Docusaurus docs build by introducing a local plugin that (1) injects JSON-LD structured data into the generated HTML and (2) generates an llms.txt index of docs pages during postBuild. It also removes an ineffective robots.txt that wasn’t being served from the origin root, and adds CI enforcement that llms.txt is generated and non-empty.
Changes:
- Add
docs/plugins/swm-geo.jsDocusaurus plugin to inject JSON-LD and generatebuild/llms.txt. - Register the plugin in
docs/docusaurus.config.js. - Remove
docs/static/robots.txtand add a CI step validatingbuild/llms.txtpresence/content.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| docs/static/robots.txt | Removes a non-origin robots.txt that wouldn’t apply at the site root. |
| docs/plugins/swm-geo.js | Adds JSON-LD injection and build-time llms.txt generation from built routes/pages. |
| docs/docusaurus.config.js | Registers the new local Docusaurus plugin. |
| .github/workflows/docs-build.yml | Enforces llms.txt existence and that it lists at least one page. |
Suppressed comments (2)
docs/plugins/swm-geo.js:83
- Because
routeBasePathis '/', most docs routes won’t matchSECTIONS[...]and will fall back toPages. If the intent is for docs to be grouped as "Documentation", use that as the default section and only override for known non-doc sections (e.g. blog/examples).
const section = SECTIONS[relative.split('/')[0]] ?? 'Pages';
const line = `- [${page.title}](${url.replace(/\/$/, '')}${route})${page.description ? `: ${page.description}` : ''}`;
docs/plugins/swm-geo.js:93
- If docs routes are treated as "Documentation" by default (see section selection above), the
'Pages'section label becomes misleading/unreachable for this site. Consider removing it from the emitted section order to keep the llms.txt structure aligned with actual grouping.
for (const section of ['Documentation', 'Examples', 'Blog', 'Pages']) {
const entries = grouped.get(section);
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This site sets routeBasePath: '/', so route segments are `fundamentals`, `guides`, `api-reference` and never `docs` — the SECTIONS map never matched and every page fell into the generic `Pages` group. Sections are now derived from the page's folder when no explicit key matches, which also covers `examples` and `blog` not existing here. JSON.stringify leaves `<` unescaped, so a `</script>` inside any config value would close the tag early. Escaped to <.
szydlovsky
left a comment
There was a problem hiding this comment.
Looks ok if we resolve all the comments above
`blog` and `examples` title-case to exactly the strings the map returned, so only `docs` -> `Documentation` was ever a real rename. Section names now come from the folder a page lives in, with that one exception. Output is unchanged for every path shape: docs/ still gives Documentation, blog/ still gives Blog, examples/ still gives Examples.
Two SEO changes for the docs site. Nothing changes the rendered page.
Organizationwith the same@idas swmansion.com, plusSoftwareSourceCodefor the library, derived fromsiteConfig. The identical@idis what makes engines read the docs and the company site as one entity instead of two unrelated ones.llms.txt, generated at build — no new dependency. Lists every docs page. The docs build now fails if the file is missing or lists nothing.docs/static/robots.txtdeleted. It never did anything:robots.txtis only read from the origin root, and this one sat at/react-native-enriched-html/robots.txt. Its rules now live at the origin (Add robots.txt for the docs.swmansion.com origin software-mansion.github.io#1, merged), where they actually apply.Both come from one local plugin,
plugins/swm-geo.js, registered with a single line. The same change is going out across the docs repos; reference: software-mansion/react-native-reanimated#10332.Check: CI prints
llms.txt lists N pages.