For AI agents: the complete documentation index is available at /rspress-russian/llms.txt, the full documentation bundle is available at /rspress-russian/llms-full.txt, and this page is available as Markdown at /rspress-russian/guide/basic/ssg-md.md.
close

llms.txt (SSG-MD) Экспериментально

Хотите быстро начать? Перейдите к Быстрому старту.

Что такое SSG-MD?

Rspress предоставляет экспериментальную функцию генерации статических сайтов в Markdown (SSG-MD). В отличие от Static Site Generation (SSG), SSG-MD рендерит страницы в Markdown-файлы вместо HTML и генерирует llms.txt и llms-full.txt, что упрощает понимание и использование технической документации большими языковыми моделями.

В следующей таблице приведено сравнение SSG и SSG-MD:

СравнениеSSGSSG-MD
Полное названиеГенерация статического сайтаГенерация статического сайта в Markdown
Цель оптимизацииSEO (оптимизация для поисковых систем)GEO (оптимизация для генеративных движков)
Целевая аудиторияПоисковый веб-краулерLLM / система векторного поиска
Файл-индексsitemap.xmlllms.txt
Файл с полным контентом-llms-full.txt
Ключевой метод рендерингаrenderToStringrenderToMarkdownString
Способ доступа/guide/start/introduction.html/guide/start/introduction.md

Что такое llms.txt?

llms.txt — это новый стандартный файл, размещаемый в корне сайта, чтобы помочь большим языковым моделям лучше понимать и использовать содержимое сайта.

Поскольку у LLM ограничено контекстное окно, они обычно не могут обработать весь HTML-контент веб-сайта целиком. Преобразование сложного HTML с навигацией, рекламой и JavaScript в обычный текст также является трудной и неточной задачей. llms.txt решает эту проблему, предоставляя структурированный индекс в формате Markdown, который включает URL страниц и описания содержимого, помогая ИИ-инструментам быстро находить и понимать ключевую информацию.

Простыми словами:

  • sitemap.xml → «карта сайта» для поисковых систем
  • llms.txt → «оглавление документации» для ИИ

Пример структуры вывода:

doc_build
llms.txt
llms-full.txt
guide
start
introduction.md
...

Пример содержимого llms.txt:

# Rspress

> Rspress is a static site generator based on Rspack.

## Docs

- [Introduction](/guide/start/introduction.md): Introduction to Rspress
- [Quick Start](/guide/start/quick-start.md): Quick Start

Почему SSG-MD?

В фронтенд-фреймворках на React извлечение статической информации из динамически отрисовываемого контента часто затруднено. MDX сталкивается с той же проблемой: файлы .mdx содержат Markdown-контент, но также могут встраивать React-компоненты, что делает документацию более интерактивной. Rspress позволяет расширять документацию с помощью MDX-фрагментов, React-компонентов, хуков и TSX-маршрутов, однако такой динамический контент создаёт проблемы при преобразовании в Markdown:

  • Передача «сырого» MDX в ИИ добавляет шум от синтаксиса кода и приводит к потере отрендеренного содержимого React-компонентов.

  • Конвертация HTML в Markdown часто даёт плохой результат, из-за чего сложно гарантировать качество информации.

Генерация статического сайта (SSG) генерирует статический HTML для краулеров и улучшает SEO. SSG-MD решает похожую задачу для ИИ-инструментов: он улучшает GEO и качество статической информации для больших языковых моделей. По сравнению с преобразованием HTML в Markdown, рендеринг из виртуального DOM React даёт SSG-MD более богатый источник информации.

Поток рендеринга SSG-MD

Как работает SSG-MD?

  1. Внутри Rspress реализован метод renderToMarkdownString, аналогичный renderToString из react-dom, который рендерит React-компоненты в строки Markdown:
import { renderToMarkdownString } from 'react-render-to-markdown';

// Элементы HTML конвертируются в соответствующий синтаксис Markdown
renderToMarkdownString(
  <div>
    <strong>foo</strong>
    <span>bar</span>
  </div>,
);
// Вывод: '**foo**bar'

// Поддерживаются компоненты и хуки React
const Article = () => {
  return (
    <>
      <h1>Привет, мир</h1>
      <p>Это параграф.</p>
    </>
  );
};
renderToMarkdownString(<Article />);
// Вывод: '# Привет, мир\n\nЭто параграф.\n'

В принципе, этот API работает для любого сайта, построенного на React; подробнее смотрите react-render-to-markdown, если интересно.

  1. Rspress использует специальный плагин remark remarkSplitMdx для предварительной обработки MDX-файлов перед рендерингом. Этот плагин разделяет AST MDX, отделяя чистый Markdown-контент от JSX-компонентов: текст Markdown сериализуется в виде строковых литералов, а JSX-компоненты и MDX-выражения (например, {variable}) сохраняются как React-элементы. Это гарантирует, что Markdown-контент передаётся без изменений и не обрабатывается механизмом рендеринга React, в то время как динамические компоненты рендерятся с помощью renderToMarkdownString.

Например, следующий MDX:

# Привет

Некоторый **жирный** текст.

<PackageManagerTabs command="install rspress" />

{window.title}

Оно преобразуется в компонент следующим образом:

function _createMdxContent() {
  return (
    <>
      {'# Привет\n\nНекоторый **жирный** текст.\n'}
      <PackageManagerTabs command="install rspress" />
      {window.title}
    </>
  );
}
  1. Rspress предоставляет переменную окружения import.meta.env.SSG_MD, чтобы React-компоненты могли отличать рендеринг SSG-MD от браузерного рендеринга и настраивать свой вывод:
export function Tab({ label }: { label: string }) {
  if (import.meta.env.SSG_MD) {
    return <>{`** Это вкладка с именем ${label}**`}</>;
  }
  return <div>{label}</div>;
}
  1. Внутренняя библиотека компонентов Rspress адаптирована под SSG-MD, поэтому компоненты во время этапа SSG-MD рендерят осмысленный Markdown. Например:
<PackageManagerTabs command="create rspress@latest" />

Оно отображается как:

```sh [npm]
npm create rspress@latest
```

```sh [yarn]
yarn create rspress
```

```sh [pnpm]
pnpm create rspress@latest
```

```sh [bun]
bun create rspress@latest
```

```sh [deno]
deno init --npm rspress@latest
```

Быстрый старт

Включите опцию llms в файле rspress.config.ts:

rspress.config.ts
import { defineConfig } from '@rspress/core';

export default defineConfig({
  llms: true,
});

После выполнения rspress build в выходной директории (по умолчанию doc_build) будут дополнительно содержаться следующие файлы:

doc_build
llms.txt# ндексный файл с заголовками и описаниями в порядке навигации
llms-full.txt# Содержит Markdown-контент всех страниц
guide
start
introduction.md# Соответствующий .md файл для каждой страницы
...

Доступ к страницам осуществляется заменой суффикса .html на .md, например /guide/start/introduction.md. Для многоязычных сайтов будут созданы файлы {lang}/llms.txt и {lang}/llms-full.txt для нелокализованных языков.

Предупреждение

llms является экспериментальной функцией и может иметь проблемы со стабильностью или совместимостью. Если SSG-MD невозможно включить из-за несовместимости с SSR, используйте @rspress/plugin-llms.

Поддержка React 18

SSG-MD по умолчанию использует react-render-to-markdown@19, который поддерживает только React 19. Если вы используете React 18, установите react-render-to-markdown@18 в вашем package.json:

package.json
{
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-render-to-markdown": "^18.3.1"
  }
}

После установки Rspress автоматически определяет и использует версию react-render-to-markdown@18 из вашего проекта.

Конфигурация

Отображение в интерфейсе

При включении llms: true компоненты LlmsCopyButton и LlmsViewOptions автоматически отображаются под всеми заголовками H1, позволяя пользователям копировать Markdown-контент или открывать его в инструментах ИИ, таких как ChatGPT или Claude. Вы также можете отображать их в панели оглавления, установив placement: 'outline'.

Настройте или отключите через themeConfig.llmsUI:

rspress.config.ts
import { defineConfig } from '@rspress/core';

export default defineConfig({
  llms: true,
  themeConfig: {
    // Отключить LLMS UI
    llmsUI: false,
    // Или настроить параметры:
    // llmsUI: {
    //   injectLlmsHint: false, // Отключить подсказку с директивой для LLM в HTML/Markdown
    //   viewOptions: ['markdownLink', 'chatgpt', 'claude'],
    //   placement: 'outline', // Отображать в панели оглавления вместо размещения под заголовком H1
    // },
  },
});

Подробности см. в themeConfig.llmsUI.

Настройка llms.txt

Используйте llms.llmsTxt для формирования полного содержимого каждого создаваемого файла llms.txt:

rspress.config.ts
import { defineConfig } from '@rspress/core';

export default defineConfig({
  llms: {
    llmsTxt: ({ title, description, sections }) => {
      const sectionContent = sections
        .map(section => {
          const pages = section.pages
            .map(page => `- [${page.title}](${page.link})`)
            .join('\n');
          return `## ${section.title}\n\n${pages}`;
        })
        .join('\n\n');

      return `# ${title}

> ${description}

${sectionContent}`;
    },
  },
});

Функция обратного вызова может возвращать строку или Promise. Она выполняется один раз для каждой создаваемой комбинации языка и версии и получает следующие параметры:

  • title и description: метаданные сайта из rspress.config.ts.
  • lang и version: язык и версия текущего файла llms.txt.
  • base и siteOrigin: параметры URL, используемые для формирования ссылок в Markdown.
  • sections: страницы, сгруппированные по навигации и упорядоченные в соответствии с боковой панелью. Каждая страница содержит поля title, description, frontmatter, routePath, link, lang и version. Поле link содержит конечный URL созданного Markdown-файла.

Страницы, не соответствующие ни одному элементу навигации, помещаются в раздел Others. Главная страница локали не включается, поскольку она уже представлена названием и описанием сайта.

Настройка разбиения MDX

Когда документы содержат пользовательские компоненты, используйте remarkSplitMdxOptions для контроля того, какие компоненты сохранять или конвертировать в обычный текст при преобразовании в Markdown:

rspress.config.ts
import { defineConfig } from '@rspress/core';

export default defineConfig({
  llms: {
    remarkSplitMdxOptions: {
      excludes: [[['Demo'], '@project/components']],
    },
  },
});
  • excludes: совпавшие компоненты преобразуются в обычный текст и имеют наивысший приоритет.
  • includes: если задано, сохраняются только совпавшие компоненты; все остальные преобразуются в обычный текст.
  • Если настроены оба параметра, сначала применяется excludes, затем результат фильтруется через includes.