Skip to content

Commit 1e4c162

Browse files
docs: implement version-specific LLM manifest URLs
Generate version-specific LLM manifest files at root and add version-aware footer links to surface the correct documentation bundle based on which docs version the user is browsing. Changes: - Generate llms-2.0.txt and llms-full-2.0.txt at root for v2.0 docs - Maintain canonical llms.txt and llms-full.txt for v1.x docs - Add custom Footer component that detects doc version and updates LLM Docs link dynamically on the client side Closes #276 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 8e4c268 commit 1e4c162

File tree

3 files changed

+62
-19
lines changed

3 files changed

+62
-19
lines changed

scripts/generate-llms-full.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,10 @@ function main() {
222222
ensureDir(v2Path);
223223
fs.writeFileSync(path.join(v2Path, 'llms-full.txt'), v2Content, 'utf8');
224224
console.log(`v2.0 manifest -> /${versions.current}/llms-full.txt`);
225+
226+
// Also write v2.0 version-specific manifest at root
227+
fs.writeFileSync(path.join(buildDir, 'llms-full-2.0.txt'), v2Content, 'utf8');
228+
console.log(`v2.0 version-specific manifest -> /llms-full-2.0.txt`);
225229
}
226230

227231
// Write canonical manifest at root (based on lastVersion)

scripts/generate-llms.js

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -233,16 +233,6 @@ function collectSections(docsDir, repoRawBaseUrl) {
233233
return sections;
234234
}
235235

236-
function resolveDocsSourceDir() {
237-
const versionedDocsDir = path.join(__dirname, '..', 'versioned_docs', 'version-1.x');
238-
239-
if (fs.existsSync(versionedDocsDir)) {
240-
return versionedDocsDir;
241-
}
242-
243-
return path.join(__dirname, '..', 'docs');
244-
}
245-
246236
function renderSection(section) {
247237
const lines = [`## ${section.title}`, ''];
248238

@@ -254,10 +244,7 @@ function renderSection(section) {
254244
return lines.join('\n');
255245
}
256246

257-
function main() {
258-
const docsDir = resolveDocsSourceDir();
259-
const buildDir = path.join(__dirname, '..', 'build');
260-
const outputFile = path.join(buildDir, 'llms.txt');
247+
function generateManifest(docsDir, outputPath, fullManifestUrl) {
261248
const siteBaseUrl = getSiteBaseUrl();
262249
const repoRawBaseUrl = getRepoRawBaseUrl();
263250
const siteTitle = config.title || 'Documentation';
@@ -268,15 +255,13 @@ function main() {
268255
links: [
269256
{
270257
title: `${siteTitle} full documentation bundle`,
271-
url: new URL('llms-full.txt', siteBaseUrl).toString(),
258+
url: fullManifestUrl,
272259
note: 'Single-file bundle of the complete documentation set.',
273260
},
274261
],
275262
};
276263
const renderedSections = [...sections, optionalSection].map(renderSection).join('\n\n');
277264

278-
ensureDir(buildDir);
279-
280265
const content = [
281266
`# ${siteTitle}`,
282267
'',
@@ -288,9 +273,32 @@ function main() {
288273
'',
289274
].join('\n');
290275

291-
fs.writeFileSync(outputFile, content, 'utf8');
276+
fs.writeFileSync(outputPath, content, 'utf8');
277+
}
292278

293-
console.log('llms.txt generated successfully:', outputFile);
279+
function main() {
280+
const buildDir = path.join(__dirname, '..', 'build');
281+
const siteBaseUrl = getSiteBaseUrl();
282+
283+
ensureDir(buildDir);
284+
285+
// Generate v1.x manifest (canonical)
286+
const v1DocsDir = path.join(__dirname, '..', 'versioned_docs', 'version-1.x');
287+
if (fs.existsSync(v1DocsDir)) {
288+
const v1OutputFile = path.join(buildDir, 'llms.txt');
289+
const v1FullUrl = new URL('llms-full.txt', siteBaseUrl).toString();
290+
generateManifest(v1DocsDir, v1OutputFile, v1FullUrl);
291+
console.log('v1.x llms.txt generated successfully:', v1OutputFile);
292+
}
293+
294+
// Generate v2.0 manifest (version-specific)
295+
const v2DocsDir = path.join(__dirname, '..', 'docs');
296+
if (fs.existsSync(v2DocsDir)) {
297+
const v2OutputFile = path.join(buildDir, 'llms-2.0.txt');
298+
const v2FullUrl = new URL('llms-full-2.0.txt', siteBaseUrl).toString();
299+
generateManifest(v2DocsDir, v2OutputFile, v2FullUrl);
300+
console.log('v2.0 llms-2.0.txt generated successfully:', v2OutputFile);
301+
}
294302
}
295303

296304
main();

src/theme/Footer/index.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import React, { useEffect, useRef } from 'react';
2+
import Footer from '@theme-original/Footer';
3+
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment';
4+
5+
export default function FooterWrapper(props) {
6+
const footerRef = useRef(null);
7+
8+
useEffect(() => {
9+
if (!ExecutionEnvironment.canUseDOM || !footerRef.current) {
10+
return;
11+
}
12+
13+
// Detect if we're on v2.0 docs based on URL
14+
const isV2Docs = window.location.pathname.startsWith('/docs/2.0/');
15+
16+
// Find and update the LLM Docs link in the footer
17+
const llmDocsLink = footerRef.current.querySelector('a[href*="llms-full.txt"]');
18+
if (llmDocsLink) {
19+
const targetUrl = isV2Docs
20+
? 'https://durable-workflow.com/llms-full-2.0.txt'
21+
: 'https://durable-workflow.com/llms-full.txt';
22+
llmDocsLink.setAttribute('href', targetUrl);
23+
}
24+
}, []);
25+
26+
return (
27+
<div ref={footerRef}>
28+
<Footer {...props} />
29+
</div>
30+
);
31+
}

0 commit comments

Comments
 (0)