diff --git a/packages/gitbook/src/components/PageBody/PageBody.tsx b/packages/gitbook/src/components/PageBody/PageBody.tsx
index 2e5e6a630..a24d73140 100644
--- a/packages/gitbook/src/components/PageBody/PageBody.tsx
+++ b/packages/gitbook/src/components/PageBody/PageBody.tsx
@@ -4,6 +4,7 @@ import type { JSONDocument, RevisionPageDocument, SiteInsightsDisplayContext } f
import { getSpaceLanguage } from '@/intl/server';
import { t } from '@/intl/translate';
import { hasFullWidthBlock, hasMoreThan, hasTopLevelBlock, isNodeEmpty } from '@/lib/document';
+import { getLLMsTxtURL, getPageMarkdownURL } from '@/lib/llms-directive';
import type { AncestorRevisionPage } from '@/lib/pages';
import { tcls } from '@/lib/tailwind';
import { DocumentView, DocumentViewSkeleton } from '../DocumentView';
@@ -88,6 +89,7 @@ export async function PageBody(props: {
)}
>
+
{page.cover && page.layout.cover && page.layout.coverSize === 'hero' ? (
) : null}
@@ -160,3 +162,17 @@ export async function PageBody(props: {
);
}
+
+function LLMsTxtPageDirective(props: {
+ context: GitBookSiteContext;
+ page: RevisionPageDocument;
+}) {
+ const { context, page } = props;
+
+ return (
+
+ For the complete documentation index, see
llms.txt.
+ This page is also available as
Markdown.
+
+ );
+}
diff --git a/packages/gitbook/src/lib/llms-directive.test.ts b/packages/gitbook/src/lib/llms-directive.test.ts
new file mode 100644
index 000000000..b6829f344
--- /dev/null
+++ b/packages/gitbook/src/lib/llms-directive.test.ts
@@ -0,0 +1,39 @@
+import { describe, expect, it } from 'bun:test';
+import type { RevisionPageDocument } from '@gitbook/api';
+import type { GitBookSiteContext } from './context';
+import { createLinker } from './links';
+import {
+ getLLMsTxtURL,
+ getPageMarkdownURL,
+ renderLLMsTxtMarkdownDirective,
+} from './llms-directive';
+
+describe('llms directive', () => {
+ const context = {
+ linker: createLinker({
+ host: 'docs.company.com',
+ siteBasePath: '/docs',
+ spaceBasePath: '/docs/v1',
+ }),
+ } as GitBookSiteContext;
+
+ const page = {
+ path: 'guides/start',
+ } as RevisionPageDocument;
+
+ it('links llms.txt from the site root', () => {
+ expect(getLLMsTxtURL(context)).toBe('https://docs.company.com/docs/llms.txt');
+ });
+
+ it('links page markdown from the current space', () => {
+ expect(getPageMarkdownURL(context, page)).toBe(
+ 'https://docs.company.com/docs/v1/guides/start.md'
+ );
+ });
+
+ it('renders a markdown blockquote directive', () => {
+ expect(renderLLMsTxtMarkdownDirective(context, page)).toBe(
+ '> For the complete documentation index, see [llms.txt](https://docs.company.com/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.company.com/docs/v1/guides/start.md).'
+ );
+ });
+});
diff --git a/packages/gitbook/src/lib/llms-directive.ts b/packages/gitbook/src/lib/llms-directive.ts
new file mode 100644
index 000000000..77e3489c3
--- /dev/null
+++ b/packages/gitbook/src/lib/llms-directive.ts
@@ -0,0 +1,29 @@
+import type { RevisionPageDocument, RevisionPageGroup } from '@gitbook/api';
+import type { GitBookSiteContext } from './context';
+
+/**
+ * Return the URL for the site-level llms.txt file.
+ */
+export function getLLMsTxtURL(context: GitBookSiteContext): string {
+ return context.linker.toAbsoluteURL(context.linker.toPathInSite('llms.txt'));
+}
+
+/**
+ * Return the URL for the markdown version of a page.
+ */
+export function getPageMarkdownURL(
+ context: GitBookSiteContext,
+ page: RevisionPageDocument | RevisionPageGroup
+): string {
+ return `${context.linker.toAbsoluteURL(context.linker.toPathInSpace(page.path))}.md`;
+}
+
+/**
+ * Render the agent-facing directive that points agents to the site index.
+ */
+export function renderLLMsTxtMarkdownDirective(
+ context: GitBookSiteContext,
+ page: RevisionPageDocument | RevisionPageGroup
+): string {
+ return `> For the complete documentation index, see [llms.txt](${getLLMsTxtURL(context)}). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as [Markdown](${getPageMarkdownURL(context, page)}).`;
+}
diff --git a/packages/gitbook/src/routes/markdownPage.ts b/packages/gitbook/src/routes/markdownPage.ts
index 5848e204b..02445b26d 100644
--- a/packages/gitbook/src/routes/markdownPage.ts
+++ b/packages/gitbook/src/routes/markdownPage.ts
@@ -1,6 +1,7 @@
import type { GitBookSiteContext } from '@/lib/context';
import { getExposableError } from '@/lib/data';
import { linkerWithMarkdownPages } from '@/lib/links';
+import { renderLLMsTxtMarkdownDirective } from '@/lib/llms-directive';
import { getMarkdownForPage } from '@/lib/markdownPage';
import {
type ResolvedPagePath,
@@ -30,7 +31,7 @@ export async function servePageMarkdown(baseContext: GitBookSiteContext, pagePat
if (baseContext.displayAgentInstructions === false) {
return markdownPage;
}
- return `${markdownPage}${renderAskFooter(context, pageLookup)}`;
+ return `${renderLLMsTxtMarkdownDirective(context, pageLookup.page)}\n\n${markdownPage}${renderAskFooter(context, pageLookup)}`;
});
}