Skip to content

Commit be6db33

Browse files
authored
chore: add /llms.txt containg raw markdown for each docs page (#1322)
That way LLMs have it easier getting a clean version of the docs
1 parent 5fb4ef8 commit be6db33

File tree

7 files changed

+62
-36
lines changed

7 files changed

+62
-36
lines changed

apps/svelte.dev/src/lib/components/PageControls.svelte

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<script lang="ts">
2+
import { page } from '$app/state';
23
import { Icon } from '@sveltejs/site-kit/components';
34
45
interface Props {
56
repo: string;
7+
llms?: boolean;
68
prev: null | {
79
path: string;
810
title: string;
@@ -13,13 +15,18 @@
1315
};
1416
}
1517
16-
let { repo, prev, next }: Props = $props();
18+
let { repo, prev, next, llms }: Props = $props();
1719
</script>
1820

1921
<p class="edit">
2022
<a href={repo}>
2123
<Icon name="edit" /> Edit this page on GitHub
2224
</a>
25+
{#if llms}
26+
<a href={page.url.pathname.replace(/\/$/, '') + '/llms.txt'}>
27+
<Icon name="contents" /> llms.txt
28+
</a>
29+
{/if}
2330
</p>
2431

2532
<div class="controls">
@@ -44,9 +51,13 @@
4451
position: relative;
4552
margin: 6rem 0 2rem 0;
4653
font: var(--sk-font-ui-small);
54+
display: flex;
4755
4856
a {
4957
text-decoration: none;
58+
&:first-of-type {
59+
margin-right: 5rem;
60+
}
5061
}
5162
5263
:global(svg) {

apps/svelte.dev/src/lib/server/llms.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { index } from './content';
55
interface GenerateLlmContentOptions {
66
ignore?: string[];
77
minimize?: Partial<MinimizeOptions>;
8-
sections: Section[];
8+
topics: Topic[];
99
}
1010

1111
interface MinimizeOptions {
@@ -17,7 +17,7 @@ interface MinimizeOptions {
1717
normalize_whitespace: boolean;
1818
}
1919

20-
interface Section {
20+
interface Topic {
2121
slug: string;
2222
title: string;
2323
}
@@ -34,13 +34,13 @@ const defaults: MinimizeOptions = {
3434
export function generate_llm_content(options: GenerateLlmContentOptions): string {
3535
let content = '';
3636

37-
for (const section of options.sections) {
38-
if (options.sections.length > 1) {
39-
content += `# Start of ${section.title} documentation\n\n`;
37+
for (const topic of options.topics) {
38+
if (options.topics.length > 1) {
39+
content += `# Start of ${topic.title} documentation\n\n`;
4040
}
4141

4242
for (const [path, document] of Object.entries(index)) {
43-
if (!path.startsWith(`docs/${section.slug}`)) continue;
43+
if (!path.startsWith(`docs/${topic.slug}`)) continue;
4444

4545
if (options.ignore?.some((pattern) => minimatch(path, pattern))) {
4646
if (dev) console.log(`❌ Ignored by pattern: ${path}`);
@@ -61,14 +61,14 @@ export function generate_llm_content(options: GenerateLlmContentOptions): string
6161
return content;
6262
}
6363

64-
export const sections: Section[] = [
64+
export const topics: Topic[] = [
6565
{ slug: 'svelte', title: 'Svelte' },
6666
{ slug: 'kit', title: 'SvelteKit' },
6767
{ slug: 'cli', title: 'the Svelte CLI' }
6868
];
6969

70-
export function get_documentation_title(section: Section): string {
71-
return `This is the developer documentation for ${section.title}.`;
70+
export function get_documentation_title(topic: Topic): string {
71+
return `This is the developer documentation for ${topic.title}.`;
7272
}
7373

7474
function minimize_content(content: string, options?: Partial<MinimizeOptions>): string {

apps/svelte.dev/src/routes/docs/[topic]/[...path]/+page.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
</div>
8484

8585
<PageControls
86+
llms
8687
{repo}
8788
prev={data.document.prev && {
8889
title: data.document.prev.title,
Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,46 @@
11
import { error } from '@sveltejs/kit';
2-
import { generate_llm_content, get_documentation_title, sections } from '$lib/server/llms';
2+
import { docs } from '$lib/server/content.js';
3+
import { generate_llm_content, get_documentation_title, topics } from '$lib/server/llms';
34

45
export const prerender = true;
56

67
export function entries() {
7-
return sections.map((section) => {
8-
const [topic, ...rest] = section.slug.split('/');
9-
return { topic, path: rest.join('/') };
8+
return topics.map((topic) => {
9+
return { topic: topic.slug, path: '' };
1010
});
1111
}
1212

1313
export function GET({ params }) {
14-
const pkg = params.path ? `${params.topic}/${params.path}` : params.topic;
14+
if (params.path) {
15+
const page = docs.pages[`docs/${params.topic}/${params.path}`];
1516

16-
const section = sections.find((s) => s.slug === pkg);
17-
18-
if (!section) {
19-
error(404, 'Not Found');
20-
}
17+
if (!page) {
18+
error(404, 'Not Found');
19+
}
2120

22-
const prefix = `<SYSTEM>${get_documentation_title(section)}</SYSTEM>`;
23-
const content = `${prefix}\n\n${generate_llm_content({ sections: [section] })}`;
21+
return new Response(page.body, {
22+
status: 200,
23+
headers: {
24+
'Content-Type': 'text/plain; charset=utf-8',
25+
'Cache-Control': 'public, max-age=3600'
26+
}
27+
});
28+
} else {
29+
const topic = topics.find((s) => s.slug === params.topic);
2430

25-
return new Response(content, {
26-
status: 200,
27-
headers: {
28-
'Content-Type': 'text/plain; charset=utf-8',
29-
'Cache-Control': 'public, max-age=3600'
31+
if (!topic) {
32+
error(404, 'Not Found');
3033
}
31-
});
34+
35+
const prefix = `<SYSTEM>${get_documentation_title(topic)}</SYSTEM>`;
36+
const content = `${prefix}\n\n${generate_llm_content({ topics: [topic] })}`;
37+
38+
return new Response(content, {
39+
status: 200,
40+
headers: {
41+
'Content-Type': 'text/plain; charset=utf-8',
42+
'Cache-Control': 'public, max-age=3600'
43+
}
44+
});
45+
}
3246
}

apps/svelte.dev/src/routes/llms-full.txt/+server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { generate_llm_content, sections } from '$lib/server/llms';
1+
import { generate_llm_content, topics } from '$lib/server/llms';
22

33
export const prerender = true;
44

55
export function GET() {
6-
const content = `<SYSTEM>This is the full developer documentation for Svelte and SvelteKit.</SYSTEM>\n\n${generate_llm_content({ sections })}`;
6+
const content = `<SYSTEM>This is the full developer documentation for Svelte and SvelteKit.</SYSTEM>\n\n${generate_llm_content({ topics })}`;
77

88
return new Response(content, {
99
status: 200,

apps/svelte.dev/src/routes/llms-medium.txt/+server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { generate_llm_content, sections } from '$lib/server/llms';
1+
import { generate_llm_content, topics } from '$lib/server/llms';
22

33
export function GET() {
44
const main_content = generate_llm_content({
5-
sections,
5+
topics,
66
ignore: [
77
// Svelte ignores
88
'docs/svelte/legacy/**/*',

apps/svelte.dev/src/routes/llms.txt/+server.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import { get_documentation_title, sections } from '$lib/server/llms';
1+
import { get_documentation_title, topics } from '$lib/server/llms';
22
import template from './template.md?raw';
33

44
const DOMAIN = `https://svelte.dev`;
55

66
export const prerender = true;
77

88
export function GET() {
9-
const package_docs = sections.map(
10-
(section) =>
11-
`- [${section.title} documentation](${DOMAIN}/docs/${section.slug}/llms.txt): ${get_documentation_title(section)}`
9+
const package_docs = topics.map(
10+
(topic) =>
11+
`- [${topic.title} documentation](${DOMAIN}/docs/${topic.slug}/llms.txt): ${get_documentation_title(topic)}`
1212
);
1313

1414
const content = template.replace('%PACKAGE_DOCS%', package_docs.join('\n'));

0 commit comments

Comments
 (0)