Astro での llms.txt

2つの方法があります。即時デプロイするならpublic/にファイルを置き、コンテンツコレクションから動的に生成するならTypeScriptエンドポイントを使用します。

最終更新:

アプローチ1、次の場所に静的ファイルを配置: public/

最も簡単な方法です。プロジェクトのルートにある public/llms.txt にプレーンテキストファイルを作成します。Astro は public/ ディレクトリ全体を public/llms.txt に Astro はプロジェクトルートの public/ ディレクトリをそのまま dist/ の実行時に astro build、そのためファイルは /llms.txt 設定不要。

static approach, public/llms.txt
# Place the file at: public/llms.txt
# Astro copies everything in public/ to the output directory as-is.
# Result: served at https://yoursite.com/llms.txt, no code changes needed.

# After deploy, verify:
curl -I https://yoursite.com/llms.txt
# Expected: HTTP/2 200 | Content-Type: text/plain

使用すべき場面: コンテンツが頻繁には変わらず、ビルド時の オーバーヘッドをゼロにしたい場合、またはファイルを手動で管理する場合に適しています。Cloudflare Pages、Vercel、Netlify、 その他のあらゆるAstroホストで同じように動作します。

アプローチ 2、TypeScript エンドポイント( getCollection()

Astro は二重拡張子 .txt.ts を次のように扱います: src/pages/llms.txt.ts 次で応答するAPIエンドポイントとして扱います: /llms.txt。SSGモード(デフォルト)では、Astroがこれを静的な dist/llms.txt ビルド時に静的な dist/llms.txt に生成され、ランタイムコストはありません。

src/pages/llms.txt.ts
// src/pages/llms.txt.ts
// Astro treats src/pages/foo.ext.ts as a route for /foo.ext
// In SSG mode (default), it pre-renders to dist/llms.txt at build time.

import type { APIRoute } from 'astro';
import { getCollection } from 'astro:content';

export const GET: APIRoute = async () => {
  // Replace 'docs' with your actual content collection name
  const docs = await getCollection('docs');

  const lines = [
    '# My Site',
    '',
    '> One-sentence description of what this site is about.',
    '',
    '## Documentation',
    '',
    ...docs
      .filter((d) => !d.data.draft)
      .sort((a, b) => (a.data.order ?? 999) - (b.data.order ?? 999))
      .map((d) => `- [${d.data.title}](https://yoursite.com/${d.slug}/): ${d.data.summary ?? ''}`.trimEnd()),
    '',
    '## Optional',
    '',
    '- [Changelog](https://yoursite.com/changelog/): version history.',
  ];

  return new Response(lines.join('\n'), {
    headers: { 'Content-Type': 'text/plain; charset=utf-8' },
  });
};

要点:

  • 置換 'docs' 実際のコレクション名を指定して src/content/config.ts.
  • マッピングの前に下書きを除外する: !d.data.draft.
  • 各行の注記(: short note) は任意ですが、強く推奨されます。これにより、 LLMが各ページに関するコンテキストを、自ら取得することなく得ることができます。
  • 必ず設定するのは Content-Type: text/plain; charset=utf-8 回答内。

追加 llms-full.txt

llms-full.txt コンパニオンファイルは各ページの本文全体をインライン化します。 コーパス全体を一度に必要とするRAGパイプラインやLLMクライアントに便利です。並行するエンドポイントを作成します:

src/pages/llms-full.txt.ts
// src/pages/llms-full.txt.ts
// Generates the full-content companion file.
// Each entry gets its full Markdown body inlined, useful for RAG pipelines.

import type { APIRoute } from 'astro';
import { getCollection } from 'astro:content';

export const GET: APIRoute = async () => {
  const docs = await getCollection('docs');
  const sections: string[] = [];

  for (const doc of docs.filter((d) => !d.data.draft)) {
    sections.push(
      `# ${doc.data.title}`,
      '',
      `URL: https://yoursite.com/${doc.slug}/`,
      '',
      doc.body,   // raw Markdown, no HTML, ideal for LLMs (Astro 4+)
      '',
      '---',
      '',
    );
  }

  return new Response(sections.join('\n'), {
    headers: { 'Content-Type': 'text/plain; charset=utf-8' },
  });
};

doc.body LLMに最適な生のMarkdown(Astro 4以降で利用可能)が含まれています。 HTMLタグがなく、意味論的にクリーンなテキストです。Astro 3の場合は、 render() 単純な正規表現を使用して、helper タグと strip タグを処理する。

ビルド後に検証する

verify
# Build the project
npx astro build

# Check static output (works for both approaches in SSG mode)
cat dist/llms.txt

# Or start preview server and curl:
npx astro preview &
curl http://localhost:4321/llms.txt
curl http://localhost:4321/llms-full.txt

デプロイ後、公開URLを バリデーター 仕様への適合を確認します。H1が正確に1つ、リンク構文が有効(- [title](https://...))、すべてのURLが絶対URLで、空のセクションがないこと。

どのアプローチを選ぶか

  • 静的 public/llms.txt、更新頻度の低いサイトに最適です。 オーバーヘッドはゼロで、TypeScriptは不要、どこでも動作します。
  • TypeScriptエンドポイント src/pages/llms.txt.ts。多数の自動生成ページを持つドキュメントサイトに最適です。手動編集を行わなくても、ビルドのたびにファイルが自動的に同期されます。

完全な作成ガイド · Next.js ガイド · WordPressガイド

ソース