Reactive EngineeringRE Docs
Руководства

Настроить портал

Развертывание шаблона под новый портал — название, репозиторий, навигация и заглушки.

Настройка нового портала сводится к правке lib/portal.config.ts. Компоненты и layout читают значения оттуда.

Обязательный минимум

Название и описание

lib/portal.config.ts
export const portalConfig = {
  name: 'Payment Gateway Documentation',
  shortName: 'PG Docs',
  tagline: 'Документация платежного шлюза',
  description: 'Подключение, спецификации API и эксплуатационные материалы.',
  // ...
};
ПолеГде отображается
nameШаблон <title> всех страниц, Open Graph-изображения.
shortNameПодпись рядом с логотипом в навбаре.
taglineЗаголовок hero-блока главной страницы.
descriptionПодзаголовок hero-блока и meta description.

Координаты репозитория

git: {
  user: 'ReactiveEngineering',
  repo: 'payment-gateway-docs',
  branch: 'main',
},

Отсюда формируются ссылка на репозиторий в навбаре и кнопка «View on GitHub» на каждой странице документации.

Проверьте имя репозитория

Несовпадение repo с фактическим именем репозитория даёт битые ссылки на каждой странице документации — внешне портал при этом работает нормально.

Список продуктов

products: [
  {
    slug: 'payment-gateway',
    title: 'Payment Gateway',
    description: 'Платежный шлюз: подключение, API и эксплуатация.',
    icon: 'CreditCard',
  },
],

slug — имя каталога в content/docs/. Подробнее: Добавить продукт.

Адрес портала

.env
NEXT_PUBLIC_SITE_URL=https://docs.example.com

Значение попадает в metadataBase и делает Open Graph-ссылки абсолютными.

Связанные порталы и навигация

Массив externalPortals формирует и пункты верхней навигации, и карточки в нижней части главной страницы.

externalPortals: [
  {
    title: 'Swagger',
    description: 'Интерактивные спецификации OpenAPI.',
    href: 'https://swagger.example.com',
    external: true,
  },
],
ПолеНазначение
hrefВнутренний путь или полный внешний адрес.
externaltrue — ссылка открывается в новой вкладке.

Чтобы убрать блок связанных порталов целиком, оставьте массив пустым — раздел на главной странице не отрендерится.

Эта навигация отображается только на главной странице и на заглушках. В разделе документации она скрыта: боковое меню там отведено под структуру документации, а возврат на / выполняется по логотипу в его заголовке.

Поведение бокового меню

app/docs/layout.tsx
links={[]}
sidebar={{ defaultOpenLevel: EXPAND_ALL_LEVELS }}
tabMode="auto"
ПараметрДействие
links={[]}Убирает навигацию портала из бокового меню.
sidebar.defaultOpenLevelРазворачивает разделы при первой отрисовке: папка открыта, если defaultOpenLevel >= depth. Константа EXPAND_ALL_LEVELS заведомо больше любой реальной вложенности, поэтому раскрыто всё дерево — включая разделы, добавленные позже.
tabsСписок продуктов для переключателя, см. ниже.
tabMode="auto"Рисует переключатель выпадающим списком над боковым меню.

Как свернуть дерево

Значение Fumadocs по умолчанию — 0, все папки свёрнуты. Уменьшите defaultOpenLevel до 1, чтобы открыть только верхний уровень. Поведение отдельной папки переопределяется полем defaultOpen в её meta.json.

Переключатель продуктов на корневой странице

Fumadocs строит вкладки из каталогов с "root": true, но рисует выпадающий список только пока какая-то вкладка активна. На /docs читатель находится вне любого продукта, поэтому переключатель исчезал именно там, где он нужнее всего.

Поэтому список вкладок собирается вручную, и первым элементом идёт обзорная страница:

app/docs/layout.tsx
const tabs: LayoutTab[] = [
  {
    title: 'Обзор портала',
    description: 'Точка входа и правила навигации по порталу',
    url: docsRoute,
    icon: <House />,
  },
  ...getLayoutTabs(tree),
];

Вкладка без привязки к дереву страниц ($folder) активна по вложенному URL, поэтому /docs делает её активной — как и любая страница внутри. Выпадающий список выбирает последнюю подходящую вкладку, отсюда порядок: внутри продукта побеждает его собственная вкладка, на корне остаётся только обзор.

Обзорная запись попадает и в сам список — это одновременно путь назад к /docs.

Страницы-заглушки

/swagger и /flows по умолчанию показывают страницу «раздел в подготовке». Тексты и планируемый адрес задаются в конфигурации:

placeholders: {
  swagger: {
    title: 'Swagger-портал',
    eyebrow: 'Раздел в подготовке',
    description: 'Здесь появится интерактивная спецификация OpenAPI.',
    target: 'https://swagger.example.com',
  },
},

Замена заглушки редиректом

app/swagger/page.tsx
import { redirect } from 'next/navigation';
import { portalConfig } from '@/lib/portal.config';

export default function SwaggerPage() {
  redirect(portalConfig.placeholders.swagger.target);
}

Альтернатива без страницы — редирект на уровне конфигурации Next.js:

next.config.mjs
const config = {
  reactStrictMode: true,
  output: 'standalone',
  async redirects() {
    return [
      {
        source: '/swagger',
        destination: 'https://swagger.example.com',
        permanent: false,
      },
    ];
  },
};

Удаление раздела

Удалите каталог app/swagger/ и соответствующую запись из externalPortals и placeholders.

Смена языка интерфейса

Атрибут lang задан в app/layout.tsx:

<html lang="ru" suppressHydrationWarning>

Подписи навигации находятся в lib/layout.shared.tsx, тексты главной страницы — в app/page.tsx и lib/portal.config.ts.

Брендинг

Палитра, шрифты и логотипы описаны в разделе Бренд и стили.

On this page