Skip to content

Commit e6ea243

Browse files
committed
Group docs pages by folder and escape the JSON-LD
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 <.
1 parent 59ef832 commit e6ea243

1 file changed

Lines changed: 30 additions & 3 deletions

File tree

docs/plugins/swm-geo.js

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,22 @@ const path = require('node:path');
33

44
const ORGANIZATION_ID = 'https://swmansion.com/#organization';
55
const SECTIONS = { docs: 'Documentation', blog: 'Blog', examples: 'Examples' };
6+
const ACRONYMS = { api: 'API', ui: 'UI' };
7+
8+
const titleCase = (segment) =>
9+
segment
10+
.split(/[-_]/)
11+
.map((word) => ACRONYMS[word] ?? word.replace(/^./, (c) => c.toUpperCase()))
12+
.join(' ');
13+
14+
// With `routeBasePath: '/'` there is no `docs/` prefix to match, so group by
15+
// the folder the page lives in instead of dropping everything into `Pages`.
16+
const sectionOf = (relative) => {
17+
const parts = relative.split('/').filter(Boolean);
18+
if (SECTIONS[parts[0]]) return SECTIONS[parts[0]];
19+
if (parts.length < 2) return 'Pages';
20+
return titleCase(parts[0]);
21+
};
622

723
const decode = (value) =>
824
value
@@ -79,7 +95,7 @@ function buildLlmsTxt({ siteConfig, routesPaths, readPage }) {
7995
const page = describe(html, title);
8096
if (!page.title) continue;
8197

82-
const section = SECTIONS[relative.split('/')[0]] ?? 'Pages';
98+
const section = sectionOf(relative);
8399
const line = `- [${page.title}](${url.replace(/\/$/, '')}${route})${page.description ? `: ${page.description}` : ''}`;
84100

85101
if (!grouped.has(section)) grouped.set(section, []);
@@ -89,7 +105,16 @@ function buildLlmsTxt({ siteConfig, routesPaths, readPage }) {
89105
const lines = [`# ${title}`];
90106
if (tagline) lines.push('', `> ${tagline}`);
91107

92-
for (const section of ['Documentation', 'Examples', 'Blog', 'Pages']) {
108+
const preferred = ['Documentation', 'Examples', 'Blog'];
109+
const order = [
110+
...preferred.filter((section) => grouped.has(section)),
111+
...[...grouped.keys()]
112+
.filter((section) => !preferred.includes(section) && section !== 'Pages')
113+
.sort(),
114+
...(grouped.has('Pages') ? ['Pages'] : []),
115+
];
116+
117+
for (const section of order) {
93118
const entries = grouped.get(section);
94119
if (!entries?.length) continue;
95120
lines.push('', `## ${section}`, '', ...entries.sort());
@@ -116,7 +141,9 @@ module.exports = function swmGeoPlugin(context) {
116141
{
117142
tagName: 'script',
118143
attributes: { type: 'application/ld+json' },
119-
innerHTML: JSON.stringify(buildStructuredData(context.siteConfig)),
144+
innerHTML: JSON.stringify(
145+
buildStructuredData(context.siteConfig),
146+
).replace(/</g, '\\u003c'),
120147
},
121148
],
122149
};

0 commit comments

Comments
 (0)