close

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

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

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

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

Чтобы лучше понять SSG-MD, вот аналогия между 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 Rspress позволяет пользователям повышать выразительность документов через динамические возможности, такие как фрагменты MDX, React-компоненты, Hooks и TSX-маршруты. Однако эти динамические содержимые сталкиваются со следующими проблемами при конвертации в текстовый Markdown:

  • Прямой ввод MDX в ИИ включает много шумов синтаксиса кода и теряет содержимое React-компонентов

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

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

Поток рендеринга 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. Предоставляет переменную окружения import.meta.env.SSG_MD, что позволяет легко различать рендеринг в режиме SSG-MD и рендеринг в браузере внутри React-компонентов, обеспечивая более гибкую настройку контента:
export function Tab({ label }: { label: string }) {
  if (import.meta.env.SSG_MD) {
    return <>{`** Это вкладка с именем ${label}**`}</>;
  }
  return <div>{label}</div>;
}
  1. Внутренняя библиотека компонентов Rspress была адаптирована для SSG-MD, чтобы обеспечить рендеринг разумного Markdown-контента на этапе SSG-MD. Например:
<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: {
    //   viewOptions: ['markdownLink', 'chatgpt', 'claude'],
    //   placement: 'outline', // Отображать в панели оглавления вместо размещения под заголовком H1
    // },
  },
});

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

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

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

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

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