SEO и метаданные

Стартер отдаёт корректные sitemap.xml, robots.txt и метаданные Open Graph «из коробки». Ниже — где они формируются и что поменять под свой домен.

Базовый URL

Почти всё в SEO завязано на переменную NEXT_PUBLIC_APP_URL — публичный адрес сайта. Задайте её в .env под свой домен (иначе используется http://localhost:3000):

NEXT_PUBLIC_APP_URL="https://ваш-домен.ru"

Метаданные и Open Graph

Корневые метаданные задаёт src/app/[locale]/layout.tsx через generateMetadata (Metadata API Next.js): metadataBase, шаблон заголовка %s · LaunchKit, описание, ключевые слова, блоки openGraph и twitter. Тексты берутся из каталога переводов (namespace metadata), а locale подставляется по активному языку (ru_RU / en_US):

return {
  metadataBase: new URL(appUrl),
  title: { default: title, template: '%s · LaunchKit' },
  description,
  openGraph: {
    type: 'website',
    locale: locale === 'ru' ? 'ru_RU' : 'en_US',
    url: appUrl,
    siteName: 'LaunchKit',
    title,
    description,
  },
  twitter: { card: 'summary_large_image', title, description },
};

Что настроить: замените siteName (LaunchKit) на своё имя, а ключевые слова и тексты — в messages/ru.json / messages/en.json (namespace metadata).

Метаданные отдельной страницы

Любая страница переопределяет заголовок и описание, экспортируя metadata или generateMetadata. Заголовок подставляется в шаблон %s · LaunchKit:

export const metadata: Metadata = { title: 'Обзор' };

Страница поста блога, например, отдаёт title и description из фронтматтера через generateMetadata — см. «Блог и RSS».

sitemap.xml

src/app/sitemap.ts строит карту сайта для обеих локалей: русские URL без префикса, английские под /en. В неё входят статические маршруты (/, /login, /register, /blog, /ai) и все посты блога (/blog/<slug> из getAllPostSlugs()), с проставленными приоритетами:

const paths = ['/', '/login', '/register', '/blog', '/ai', ...getAllPostSlugs().map((s) => `/blog/${s}`)];

Добавили новый публичный раздел — допишите его путь в этот массив.

robots.txt

src/app/robots.ts разрешает индексацию всего, кроме приватных зон, и указывает на карту сайта:

return {
  rules: { userAgent: '*', allow: '/', disallow: ['/dashboard', '/api'] },
  sitemap: `${appUrl}/sitemap.xml`,
};

Личный кабинет (/dashboard) и API (/api) закрыты от поисковиков намеренно. Свои приватные маршруты добавляйте в disallow.

Дальше