- Страницы обоих брендов из блоков Payload (D-029): главная, цены, локации, поддержка, 4 юридические, 404 и 500. Коллекции pages (черновики и версии) и faq с местами показа, 12 типов блоков; поля sites — почта и Telegram поддержки, часы работы, SEO по умолчанию. - Карта и глобус рисуются на сервере (d3-geo), контуры во внешнем SVG через <use>; выбор локации синхронизирован между картой и сеткой. - Тексты сайта и юридические черновики на 5 языках: de, fr, es — перевод с глоссарием; seed создаёт страницы и FAQ, только если их нет, SEED_CONTENT=reset пересоздаёт. - SEO: title и описания, canonical, hreflang с x-default, sitemap.xml и robots.txt на каждый домен, картинки для соцсетей. - Статическая сборка и пересборка через revalidatePath из хуков Payload (D-030); /svc/internal/revalidate для проверки. - 404 — статичная страница со статусом 404 через proxy; на сайте только опубликованные страницы. - Производительность: Client Hints темы Payload только в админке, предзагрузка 2 файлов шрифтов вместо 6; Lighthouse mobile 97–99. - Контраст --ink-3 по WCAG AA, радиокнопки вместо div role=button. - Документация: итоги 1b, глоссарий de/fr/es, трактовки юридических черновиков подтверждены, переносимые вопросы — в этапах 3e–3h. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
47 lines
2.0 KiB
TypeScript
47 lines
2.0 KiB
TypeScript
import { withPayload } from '@payloadcms/next/withPayload'
|
|
import type { NextConfig } from 'next'
|
|
import createNextIntlPlugin from 'next-intl/plugin'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
const dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
|
|
const withNextIntl = createNextIntlPlugin('./src/i18n/request.ts')
|
|
|
|
const nextConfig: NextConfig = {
|
|
// dev открывается через nginx на доменах dev.*, без этого Next не отдаёт им ресурсы dev-сервера
|
|
allowedDevOrigins: (process.env.DEV_ALLOWED_ORIGINS ?? '').split(',').filter(Boolean),
|
|
poweredByHeader: false,
|
|
// proxy получает адрес запроса таким, каким его видит роутер Next. Иначе адрес строится
|
|
// от localhost, а роутер слушает 127.0.0.1, и любое переписывание считается внешним
|
|
skipProxyUrlNormalize: true,
|
|
turbopack: {
|
|
root: dirname,
|
|
},
|
|
webpack: (webpackConfig) => {
|
|
webpackConfig.resolve.extensionAlias = {
|
|
'.cjs': ['.cts', '.cjs'],
|
|
'.js': ['.ts', '.tsx', '.js', '.jsx'],
|
|
'.mjs': ['.mts', '.mjs'],
|
|
}
|
|
return webpackConfig
|
|
},
|
|
}
|
|
|
|
const config = withPayload(withNextIntl(nextConfig), { devBundleServerPackages: false })
|
|
|
|
/**
|
|
* withPayload вешает на все адреса Client Hints темы админки: Accept-CH, Vary и Critical-CH.
|
|
* На сайте Critical-CH заставляет Chrome повторять первый запрос страницы (лишний круг по сети
|
|
* при первом заходе), а Vary дробит кэш. Оставляем их только админке.
|
|
*/
|
|
const payloadHeaders = config.headers
|
|
config.headers = async () =>
|
|
((await payloadHeaders?.()) ?? []).map((rule) =>
|
|
rule.headers.some((header) => header.key === 'Critical-CH')
|
|
? { ...rule, source: '/admin/:path*' }
|
|
: rule,
|
|
)
|
|
|
|
export default config
|