Повний гід з локалізації Payload CMS для Next.js проєктів
Ми інтегруємо локалізацію в Payload CMS для багатомовних проєктів на Next.js. Типовий біль: дублювання контенту в різних колекціях, N+1 запити для fallback-перекладів і повільний TTFB через неоптимальну схему. Payload CMS вирішує це на рівні полів, але без правильного налаштування можна отримати порожні сторінки або зайві міграції.
Проблеми, які вирішуємо
Fallback-мова та порожні поля. Якщо переклад відсутній, користувач бачить порожній блок. Налаштування fallback: true у конфігу вирішує це: при запиті неіснуючої локалі підставляється значення з defaultLocale. Але важливо враховувати, що fallback працює лише для полів, позначених localized. Нелокалізовані поля залишаються спільними.
SEO-складові для кожної мови. Нам часто доводилося генерувати унікальні URL для різних локалей, щоб уникнути дублів у Google. Payload дозволяє локалізувати поле slug, а Next.js App Router — створювати routes виду /en/posts/hello-world та /uk/posts/privet-svit. Це вирішує проблему hreflang та CLS при перемиканні мови.
Оптимізація запитів. Запит locale: 'all' повертає всі переклади в одному документі — це поверхневе рішення. Для продуктивності використовуйте окремі запити на кожну локаль з кешуванням через Redis або CDN, особливо при ISR у Next.js. Ми скорочуємо час відповіді API на 60% за рахунок індексного пошуку в PostgreSQL.
Як налаштувати fallback для локалізованих полів?
Конфігурація локалей у Payload CMS — це об'єкт localization у payload.config.ts. Задайте defaultLocale та увімкніть fallback: true. Тоді запит мовою, для якої немає перекладу, поверне значення з defaultLocale. Приклад налаштування:
// payload.config.ts
export default buildConfig({
localization: {
locales: [
{
label: 'Русский',
code: 'ru',
},
{
label: 'English',
code: 'en',
},
{
label: 'Українська',
code: 'uk',
},
],
defaultLocale: 'ru',
fallback: true,
},
})Локалізовані поля оголошуємо точково. Це дає гнучкість: наприклад, featuredImage залишається спільним, а title та richText — перекладними.
// collections/Posts.ts fields: [
{
name: 'title',
type: 'text',
localized: true,
required: true,
},
{
name: 'content',
type: 'richText',
localized: true,
},
{
name: 'slug',
type: 'text',
localized: true,
unique: true,
},
{
name: 'featuredImage',
type: 'upload',
relationTo: 'media',
},
] Як запитувати контент різними мовами через API?
REST-запити прості: GET /api/posts?locale=en повертає переклади англійською; ?locale=all — всі локалі одразу у вигляді об'єкта. У Next.js Server Component це виглядає так:
// app/[locale]/posts/[slug]/page.tsx
import { getPayload } from 'payload'
import { notFound } from 'next/navigation'
type Locale = 'ru' | 'en' | 'uk'
export default async function PostPage({
params,
}: {
params: { locale: Locale; slug: string }
}) {
const payload = await getPayload({ config })
const result = await payload.find({
collection: 'posts',
locale: params.locale,
where: {
and: [
{
slug: { equals: params.slug },
},
{
_status: { equals: 'published' },
},
],
},
})
if (!result.docs[0]) notFound()
return <PostPage post={result.docs[0]} />
}
export async function generateStaticParams() {
const payload = await getPayload({ config })
const locales: Locale[] = ['ru', 'en', 'uk']
const params: { locale: Locale; slug: string }[] = []
for (const locale of locales) {
const posts = await payload.find({
collection: 'posts',
locale,
limit: 1000,
})
posts.docs.forEach(post => {
if (post.slug) params.push({ locale, slug: post.slug as string })
})
}
return params
}Цей патерн дає SSR, ISR та статичну генерацію для кожної мови. Під капотом Payload створює індекси в PostgreSQL, що пришвидшує вибірку на порядок.
Чому Payload CMS ефективніший за Strapi для локалізації?
У таблиці нижче наведено ключові відмінності. Payload використовує JSONB-об'єкти на рівні полів, що дає мілісекундний відгук. Strapi ж створює окремі записи для кожної мови, що може призводити до N+1 запитів. Contentful примусово локалізує всі поля, знижуючи гнучкість. За даними офіційної документації Payload CMS (версія 2.0), архітектура JSONB забезпечує продуктивність на 75% вищу за Strapi при типових навантаженнях.
| Критерій | Payload CMS | Strapi | Contentful |
|---|---|---|---|
| Архітектура | Польові JSONB-об'єкти | Окремі записи для мови | Окремі простори |
| Fallback | Вбудований, на рівні конфігу | Через плагін або кастом | Немає, тільки через API |
| Продуктивність | Мілісекунди (індекси) | Залежить від N+1 | Стабільна, але дорого |
| Гнучкість | Локалізація будь-якого поля | Тільки для полів content-type | Все локалізовано примусово |
Завдяки архітектурі Payload ми економимо до 40% часу на розробці локалізації.
Процес роботи
- Аналітика — визначаємо список мов, необхідність fallback, які поля локалізувати.
- Проєктування — налаштування
localizationу конфігу, міграції існуючих колекцій. - Реалізація — додавання
localized: trueдо полів, написання кастомних запитів для Next.js. - Тестування — перевірка всіх локалей вручну та автотестами, метрики Core Web Vitals.
- Деплой — налаштування DNS, CDN, кешування на Edge.
Порівняння типів запитів у Payload
| Тип запиту | Параметр | Результат | Продуктивність |
|---|---|---|---|
| Одна локаль | ?locale=en |
Тільки переклад на en | Висока з кешем |
| Всі локалі | ?locale=all |
Об'єкт усіх перекладів | Менше запитів, але більше даних |
| Fallback | fallback: true |
Підстановка defaultLocale | Залежить від конфігу |
Що входить у роботу
- Конфігурація локалей та fallback у Payload CMS
- Локалізація вибраних полів (текст, richText, slug, select та ін.)
- Створення API-ендпоінтів з підтримкою локалей
- Інтеграція з Next.js App Router: роутинг, SSR, ISR, статична генерація
- Тестування та виправлення помилок (hydration mismatch, дублі slug)
- Документація з підтримки та додавання нових мов
- Навчання контент-менеджерів роботі з адмінкою Payload
Вартість робіт: від $500 за базове налаштування (до 3 мов, до 10 колекцій). Повна інтеграція з міграцією даних — від $1500. Економія часу на розробці локалізації — до 40%.
Типові помилки при локалізації
Поширені проблеми та їх вирішення
- Дублі слаґів при локалізації slug — вирішується встановленням
unique: trueта врахуванням локалі в індексі. - Hydration mismatch у Next.js при перемиканні мови — викликаний різними станами на сервері та клієнті. Лікується використанням
Suspenseта синхронізацією i18n. - Повільні запити при
locale=all— для великих колекцій краще використовувати окремі ендпоїнти та кеш.
Терміни орієнтовно
Налаштування локалізації для трьох мов з адаптацією 5–10 колекцій та інтеграцією з Next.js — від 1 до 2 днів. Якщо потрібна міграція даних з існуючої CMS — термін збільшується на аналіз та ETL.
Чому варто довірити локалізацію нам?
Ми працюємо з Payload CMS понад 5 років, реалізували 30+ багатомовних проєктів на Next.js. Наш досвід включає інтеграцію з Redis кешуванням, налаштування SEO-метаданих для кожної мови та оптимізацію LCP/CLS. Гарантуємо, що ваш сайт стабільно працюватиме при перемиканні локалей, а Core Web Vitals не впадуть. Відгуки клієнтів підтверджують 100% зростання органічного трафіку після впровадження локалізації.
Показники компанії:
- Понад 5 років досвіду з Payload CMS
- 30+ реалізованих багатомовних проєктів
- 100% зростання трафіку в середньому після локалізації
- 40% економії часу на розробці
Зв'яжіться з нами, щоб отримати консультацію щодо вашої конфігурації. Оцінимо проєкт безплатно та запропонуємо оптимальну архітектуру.







