diff --git a/README.md b/README.md index a0579a5..73b9301 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Nuxt LLMs automatically generates [`llms.txt` markdown documentation](https://ll - Generates & prerenders `/llms.txt` automatically - Generate & prerenders `/llms-full.txt` when enabled - Customizable sections directly from your `nuxt.config.ts` +- `useLlmsAlternate` composable to advertise per-page markdown alternates (RFC 8288) - Integrates with Nuxt modules and your application via the runtime hooks system ## Quick Setup @@ -120,6 +121,32 @@ export default defineNuxtConfig({ }) ``` +## Per-page markdown discovery + +`/llms.txt` advertises your site at the global level, but agents crawling individual pages have no standard way to know that a markdown counterpart exists. The `useLlmsAlternate` composable solves this by emitting two discovery hints per [RFC 8288](https://www.rfc-editor.org/rfc/rfc8288): + +- `` in the document `` +- `Link: <...>; rel="alternate"; type="text/markdown"` HTTP response header + +Agents can read the `Link` header from a `HEAD` request — without parsing HTML — and switch to the markdown URL for ingestion. + +```vue + + +``` + +The composable accepts a string, a `ref`, or a getter. Falsy values are ignored, so it is safe to call before async data resolves: + +```ts +const { data: post } = await useAsyncData(/* ... */) +useLlmsAlternate(() => post.value?.markdownUrl) +``` + +This pairs naturally with `@nuxt/content`'s `/raw/.md` endpoint, but works with any markdown URL — including endpoints you serve yourself. + ## Extending the documentation using hooks The module provides a hooks system that allows you to dynamically extend both documentation formats. There are two main hooks: diff --git a/package.json b/package.json index f00fd37..5ecb1dc 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "@nuxt/kit": "^4.2.2" }, "devDependencies": { - "@nuxt/content": "^3.10.0", + "@nuxt/content": "^3.13.0", "@nuxt/devtools": "^3.1.1", "@nuxt/eslint-config": "^1.12.1", "@nuxt/module-builder": "^1.0.2", diff --git a/playground/pages/[...slug].vue b/playground/pages/[...slug].vue index bdfde44..2fcc54b 100644 --- a/playground/pages/[...slug].vue +++ b/playground/pages/[...slug].vue @@ -4,6 +4,11 @@ const route = useRoute() const { data } = await useAsyncData(() => 'posts' + route.path, async () => { return await queryCollection('content').path(route.path).first() }) + +useLlmsAlternate(() => { + const path = data.value?.path + return path && path !== '/' ? `/raw${path}.md` : null +})