close

@rspress/plugin-llms новинка

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

Warning

@rspress/plugin-llms использует remark для обработки исходных файлов MDX, поэтому он не поддерживает рендеринг динамического контента, такого как React Hooks или пользовательские компоненты.

Этот плагин предназначен только как запасное решение, когда функции SSG и SSG-MD невозможно включить из-за несовместимости кода с SSR. Рекомендуется в приоритетном порядке использовать функцию SSG-MD.

Установка

npm
yarn
pnpm
bun
deno
npm add @rspress/plugin-llms -D

Использование

1. Подключение плагина

Добавьте следующую конфигурацию в ваш файл rspress.config.ts:

// rspress.config.ts
import { defineConfig } from '@rspress/core';
import { pluginLlms } from '@rspress/plugin-llms';

export default defineConfig({
  plugins: [pluginLlms()],
});

Затем выполните команду rspress build. Во время генерации сборки плагин дополнительно создаст в выходной директории файлы llms.txt, llms-full.txt, а также отдельные markdown-файлы для каждого маршрута на основе структуры навигации и бокового меню.

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

Если вы хотите, чтобы пользователи вашего сайта документации могли лучше использовать большие языковые модели для чтения документации, вы можете добавить кнопку копирования Markdown в верхней части страницы — с тем же эффектом, что и на этом сайте.

Использование themeConfig (рекомендуемый способ)

Самый простой способ — включить llmsUI в themeConfig. Это автоматически добавит компоненты LlmsCopyButton и LlmsViewOptions под всеми заголовками H1 без необходимости писать код пользовательской темы:

rspress.config.ts
import { defineConfig } from '@rspress/core';
import { pluginLlms } from '@rspress/plugin-llms';

export default defineConfig({
  plugins: [pluginLlms()],
  themeConfig: {
    llmsUI: true,
    // Или с пользовательскими настройками:
    // llmsUI: {
    //   viewOptions: ['markdownLink', 'chatgpt', 'claude'],
    // },
  },
});

Использование своей темы

Если вам нужен больший контроль, вы можете использовать кастомную тему, чтобы добавить кнопку копирования Markdown.

Пример добавления кнопки копирования на все страницы:

theme/index.tsx
import { getCustomMDXComponent as basicGetCustomMDXComponent } from '@rspress/core/theme';
import {
  LlmsContainer,
  LlmsCopyButton,
  LlmsViewOptions,
} from '@rspress/plugin-llms/runtime';

function getCustomMDXComponent() {
  const { h1: H1, ...mdxComponents } = basicGetCustomMDXComponent();

  const MyH1 = ({ ...props }) => {
    return (
      <>
        <H1 {...props} />
        <LlmsContainer>
          <LlmsCopyButton />
          {/* Компонент LlmsViewOptions можно добавить по необходимости */}
          <LlmsViewOptions />
        </LlmsContainer>
      </>
    );
  };
  return {
    ...mdxComponents,
    h1: MyH1,
  };
}

export { getCustomMDXComponent };
export * from '@rspress/core/theme-original';

Добавляем кнопку копирования на отдельные страницы:

docs/hello-world.mdx
# Привет, мир

<LlmsContainer>
  <LlmsCopyButton />
  {/* Компонент LlmsViewOptions можно добавить по необходимости */}
  <LlmsViewOptions />
</LlmsContainer>

Пример документа

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

Плагин принимает объект-параметр со следующим типом:

  • Тип:
interface LlmsTxt {
  name: string;
  onTitleGenerate?: (context: {
    title: string | undefined;
    description: string | undefined;
  }) => string;
  onLineGenerate?: (page: PageIndexInfo) => string;
  onAfterLlmsTxtGenerate?: (llmsTxtContent: string) => string;
}

interface MdFiles {
  mdxToMd?: boolean;
  remarkPlugins?: PluggableList;
}

interface LlmsFullTxt {
  name: string;
}

export interface Options {
  llmsTxt?: false | LlmsTxt;
  mdFiles?: false | MdFiles;
  llmsFullTxt?: false | LlmsFullTxt;
  include?: (context: { page: PageIndexInfo }) => boolean;
  exclude?: (context: { page: PageIndexInfo }) => boolean;
}
  • По умолчанию:

Если интернационализация не включена, значение по умолчанию:

{
  llmsTxt: { name: 'llms.txt' },
  llmsFullTxt: { name: 'llms-full.txt' },
  mdFiles: true
}

Если интернационализация включена, будет использоваться групповая конфигурация, а значение по умолчанию:

[
  {
    llmsTxt: { name: 'llms.txt' },
    llmsFullTxt: { name: 'llms-full.txt' },
    mdFiles: true,
    include: ({ page }) => page.lang === config.lang,
  },
  // Автоматически генерируем файлы для остальных языков на основе конфигурации locales
  {
    llmsTxt: { name: `${lang}/llms.txt` },
    llmsFullTxt: { name: `${lang}/llms-full.txt` },
    mdFiles: true,
    include: ({ page }) => page.lang === lang,
  },
  // ...
];

llmsTxt

  • Тип: false | LlmsTxt
import type { PageIndexInfo } from '@rspress/core';

export interface LlmsTxt {
  name: string;
  onTitleGenerate?: (context: {
    title: string | undefined;
    description: string | undefined;
  }) => string;
  onLineGenerate?: (page: PageIndexInfo) => string;
  onAfterLlmsTxtGenerate?: (llmsTxtContent: string) => string;
}
  • Значение по умолчанию: { name: 'llms.txt' }

Генерировать ли файл llms.txt, либо кастомизировать его содержимое через хуки.

Формат файла llms.txt по умолчанию выглядит так:

# {title}

> {description}

## {nav1.title}

- [{page.title}]({ page.routePath }): {page.frontmatter.description}

## {nav2.title}

- [{page.title}]({ page.routePath }): {page.frontmatter.description}

Вы можете изменить отдельные части через хуки:

  • onTitleGenerate: кастомизировать заголовок и секцию описания.
  • onLineGenerate: кастомизировать каждую строку md-файла.
  • onAfterLlmsTxtGenerate: финально изменить содержимое файла llms.txt.

Например:

pluginLlms({
  llmsTxt: {
    onTitleGenerate: ({ title, description }) => {
      return `# ${title} - llms.txt

> ${description}

Rspress — это статический генератор сайтов на основе Rsbuild, который умеет генерировать llms.txt с помощью плагина `@rspress/plugin-llms`.
`;
    },
  },
});

Соответствующие результаты генерации:

# Rspress - llms.txt

> Статический генератор сайтов на базе Rsbuild

Rspress — это статический генератор сайтов на основе Rsbuild, который умеет генерировать llms.txt с помощью плагина `@rspress/plugin-llms`.

## guide

- [foo](/foo.md)

mdFiles

  • Тип: false | MdFiles
export interface MdFiles {
  mdxToMd?: boolean;
  remarkPlugins?: PluggableList;
}
  • Значение по умолчанию: { mdxToMd: false, remarkPlugins: [] }

Генерировать ли отдельный Markdown-файл для соответствующего маршрута. При значении false файл для данного маршрута создаваться не будет.

mdxToMd

  • Тип: boolean
  • Значение по умолчанию: false

Преобразовывать ли содержимое MDX в обычный Markdown. При включении MDX-файлы будут конвертироваться в MD с помощью набора стандартных правил, но возможна потеря некоторой информации (например, JSX-компонентов).

remarkPlugins

  • Тип: PluggableList
  • Значение по умолчанию: []

Вы можете передать свои remark-плагины для изменения содержимого Markdown.

llmsFullTxt

  • Тип: false | LlmsFullTxt
export interface LlmsFullTxt {
  name: string;
}
  • Значение по умолчанию: { name: 'llms-full.txt' }

Генерировать ли файл llms-full.txt. При значении false файл llms-full.txt не будет создан.

include

  • Тип: (context: { page: PageIndexInfo }) => boolean

Включать только определённые страницы при генерации, обычно используется для упрощения llms.txt.

  • Пример:

Генерировать llms.txt и связанные файлы только для страниц на английском языке:

pluginLlms({
  llmsTxt: {
    name: 'llms.txt',
  },
  llmsFullTxt: {
    name: 'llms-full.txt',
  },
  include: ({ page }) => {
    return page.lang === 'en';
  },
});

exclude

  • Тип: (context: { page: PageIndexInfo }) => boolean

Исключать определённые страницы. Выполняется после include.

  • Пример:

Исключить одну страницу внутри маршрута /foo:

pluginLlms({
  llmsTxt: {
    name: 'llms.txt',
  },
  llmsFullTxt: {
    name: 'llms-full.txt',
  },
  exclude: ({ page }) => {
    return page.routePath === '/foo';
  },
});

Пропсы UI-компонента

LlmsCopyButtonProps

  • Тип: LlmsCopyButtonProps
interface LlmsCopyButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {}

LlmsViewOptionsProps

  • Тип: LlmsViewOptionsProps
type Option =
  | {
      title: string;
      icon?: React.ReactNode;
      onClick?: () => void;
    }
  | {
      title: string;
      href: string;
      icon?: React.ReactNode;
    }
  | 'markdownLink'
  | 'chatgpt'
  | 'claude';

interface LlmsViewOptionsProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  options?: Option[];
}

options

  • Тип: Option[]
type Option =
  | {
      title: string;
      icon?: React.ReactNode;
      onClick?: () => void;
    }
  | {
      title: string;
      href: string;
      icon?: React.ReactNode;
    }
  | 'markdownLink'
  | 'chatgpt'
  | 'claude';
  • Значение по умолчанию: ['markdownLink', 'chatgpt', 'claude']

Кастомизировать пункты выпадающего меню. По умолчанию поддерживаются: «Скопировать ссылку Markdown», ChatGPT и Claude.

Одновременная генерация нескольких групп llms.txt

В некоторых случаях может понадобиться сгенерировать сразу несколько групп llms.txt, например, для сайта с i18n. В этом случае можно передать массив конфигураций:

  • Пример:
// rspress.config.ts
import { defineConfig } from '@rspress/core';
defineConfig({
  lang: 'en',
  plugins: [
    pluginLlms([
      {
        llmsTxt: {
          name: 'llms.txt',
        },
        llmsFullTxt: {
          name: 'llms-full.txt',
        },
        include: ({ page }) => page.lang === 'en',
      },
      {
        llmsTxt: {
          name: 'ru/llms.txt',
        },
        llmsFullTxt: {
          name: 'ru/llms-full.txt',
        },
        include: ({ page }) => page.lang === 'ru',
      },
    ]),
  ],
});