llms.txt لصفحات GitHub

ثلاثة نهوج لـ GitHub Pages: ملف ثابت ملتزم به في docs/ أو gh-pages، وقالب Jekyll يولّد المحتوى تلقائياً، أو سير عمل GitHub Actions للتوليد الآلي بالكامل.

آخر تحديث:

الخيار 1: ملف ثابت في docs/ أو gh-pages

أسهل نهج هو الالتزام llms.txt كملف عادي في مستودعك. ويقدّمه GitHub Pages كما هو بنوع MIME الصحيح.

GitHub Pages directory structure
# GitHub Pages, static file approach
#
# Serving from docs/ branch (most common):
#   your-repo/
#   ├── docs/
#   │   ├── index.html
#   │   └── llms.txt   ← add this file here
#   └── README.md
#
# Serving from gh-pages branch:
#   Create or switch to the gh-pages branch, then add:
#   llms.txt   ← in the branch root
#
# In repository Settings → Pages:
#   Source: Deploy from a branch
#   Branch: main (or gh-pages), Folder: /docs (or /)
#
# GitHub Pages serves it at: https://username.github.io/repo/llms.txt
# With a custom domain: https://yourdomain.com/llms.txt

يكتشف GitHub Pages الملفات النصية العادية تلقائياً ويقدمها باستخدام Content-Type: text/plain; charset=utf-8. لا حاجة إلى إعداد.

الخيار 2: Jekyll مع layout: null

إذا كان موقع GitHub Pages لديك يستخدم Jekyll (وهو الافتراضي في مستودعات كثيرة)، فسيكون الملف النصي العادي .txt سيمر الملف من دون تعديل، ولا حاجة إلى مقدمة. لكن إذا أردت من Jekyll معالجة الملف كقالب (مثلاً لإدخال متغيرات الموقع)، فأضف كتلة مقدمة تتضمن layout: null لمنع Jekyll من تغليفه في تخطيط HTML.

llms.txt, with Jekyll front matter
---
layout: null
permalink: /llms.txt
---
# My Project

> One-sentence description of what my project does.

## Documentation

- [Getting Started](https://myproject.com/docs/start/): Install and configure.
- [API Reference](https://myproject.com/docs/api/): Full endpoint catalog.

## Optional

- [Changelog](https://myproject.com/changelog/): Release history.

ويمكنك أيضاً قيادة قائمة الروابط من ملف بيانات YAML في _data/, مع إبقاء المحتوى منفصلاً عن القالب:

_data/llms_links.yml
# _data/llms_links.yml
docs:
  - title: "Getting Started"
    url: "https://myproject.com/docs/start/"
    desc: "Install and configure in minutes."
  - title: "API Reference"
    url: "https://myproject.com/docs/api/"
    desc: "Full endpoint catalog with examples."
optional:
  - title: "Changelog"
    url: "https://myproject.com/changelog/"
    desc: "Release history."
llms.txt, Jekyll template with _data
---
layout: null
permalink: /llms.txt
---
# {{ site.title }}

> {{ site.description }}

## Documentation
{% for link in site.data.llms_links.docs %}
- [{{ link.title }}]({{ link.url }}): {{ link.desc }}
{% endfor %}

## Optional
{% for link in site.data.llms_links.optional %}
- [{{ link.title }}]({{ link.url }}): {{ link.desc }}
{% endfor %}

الخيار 3: GitHub Actions للتوليد الديناميكي

بالنسبة إلى المواقع التي ينبغي إنشاء قائمة روابطها تلقائياً من محتواك، استخدم سير عمل GitHub Actions يشغّل نصاً برمجياً ويلتزم بالنتيجة مجدداً في المستودع.

.github/workflows/generate-llms-txt.yml
# .github/workflows/generate-llms-txt.yml
# Generates llms.txt from your content and commits it to the repo.
name: Generate llms.txt

on:
  push:
    branches: [main]
    paths:
      - 'docs/**'
      - 'content/**'
  workflow_dispatch:

jobs:
  generate:
    runs-on: ubuntu-latest
    permissions:
      contents: write

    steps:
      - uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Generate llms.txt
        run: node scripts/generate-llms-txt.js

      - name: Commit and push if changed
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add docs/llms.txt
          git diff --staged --quiet || git commit -m "chore: regenerate llms.txt"
          git push
scripts/generate-llms-txt.js
// scripts/generate-llms-txt.js
// Run by GitHub Actions to generate docs/llms.txt from your content
const fs = require('fs');
const path = require('path');

const SITE_URL = 'https://myproject.com';

// Example: build link list from your markdown files in docs/
const docsDir = path.join(__dirname, '..', 'docs');
const mdFiles = fs.readdirSync(docsDir)
  .filter(f => f.endsWith('.md') && f !== 'index.md');

const links = mdFiles.map(file => {
  const content = fs.readFileSync(path.join(docsDir, file), 'utf-8');
  const titleMatch = content.match(/^#\s+(.+)/m);
  const descMatch = content.match(/^>\s+(.+)/m);
  const slug = file.replace('.md', '');
  const title = titleMatch ? titleMatch[1] : slug;
  const desc = descMatch ? descMatch[1] : '';
  return `- [${title}](${SITE_URL}/docs/${slug}/): ${desc}`;
}).join('\n');

const output = [
  '# My Project',
  '',
  '> My project description.',
  '',
  '## Documentation',
  '',
  links,
  '',
  '## Optional',
  '',
  `- [Changelog](${SITE_URL}/changelog/): Release history.`,
].join('\n');

fs.writeFileSync(path.join(docsDir, 'llms.txt'), output, 'utf-8');
console.log('Generated docs/llms.txt');

يُشغّل سير العمل عند الدفع إلى main التي تعدّل أدلة المحتوى لديك، ويمكن أيضاً تشغيلها يدوياً عبر workflow_dispatch. ولا ينشئ التزاماً إلا إذا تغير الملف المنشأ فعلياً.

النطاق المخصص وCNAME

إذا كنت تستخدم نطاقاً مخصصاً (مثلاً myproject.com)، أضف CNAME ملف إلى دليل التوثيق الذي يحتوي على نطاقك. وسيقدم GitHub Pages موقعك، بما في ذلك llms.txt، في ذلك النطاق.

docs/CNAME
myproject.com

استخدم عناوين URL المطلقة في llms.txt التي تطابق نطاقك المخصص، لا الافتراضي username.github.io/repo عنوان URL.

تحقّق

Verification
curl -I https://myproject.com/llms.txt
# Expected:
# HTTP/2 200
# content-type: text/plain; charset=utf-8

curl https://myproject.com/llms.txt | head -5

أدلة ذات صلة

المصادر