@roxxel/payload-multilang
v0.0.12
Published
Polylang-style document localization for Payload CMS
Readme
@roxxel/payload-multilang
Polylang-style document localization for Payload CMS
Plugin lets editors manage each translation as its own Payload document.
Install
pnpm add @roxxel/payload-multilangQuick Start
Add the plugin to payload.config.ts and list the collections or globals that should be localized.
import { buildConfig } from 'payload'
import { payloadMultilang } from '@roxxel/payload-multilang'
export default buildConfig({
localization: false,
plugins: [
payloadMultilang({
collections: {
posts: true,
},
globals: {
'site-settings': {
label: 'Settings translations',
},
},
languages: [
{
code: 'en',
flagLabel: 'EN',
isDefault: true,
locale: 'en_US',
name: 'English',
order: 0,
},
{
code: 'uk',
flagLabel: 'UK',
locale: 'uk_UA',
name: 'Ukrainian',
order: 1,
},
],
}),
],
})Mark shared fields in the collection field config:
{
name: 'featuredImage',
type: 'upload',
relationTo: 'media',
custom: {
multilang: {
synchronize: true,
},
},
}In the Payload admin panel, enabled collections get:
- a language selector in the document sidebar
- translation status/actions for each configured language
- a
Translationsedit view for creating, connecting, and disconnecting translations - a language filter and translation shortcuts in the collection list
Enabled globals get one tab per configured language.
Admin UI
Collection lists include a language filter and translation shortcuts for each configured language.
Document edit views show the current language, linked translations, and quick actions for opening or creating missing translations.
Query by Language
Use withLanguage when querying localized collections.
import { withLanguage } from '@roxxel/payload-multilang'
const posts = await payload.find({
collection: 'posts',
where: withLanguage({
language: 'uk',
where: {
_status: {
equals: 'published',
},
},
}),
})Translation Helpers
In request-scoped code, use the WithPayload helpers with req.payload.
import {
findGlobalByLanguageWithPayload,
getDocumentTranslationWithPayload,
getDocumentTranslationsWithPayload,
updateGlobalByLanguageWithPayload,
withLanguage,
} from '@roxxel/payload-multilang'Common examples:
const state = await getDocumentTranslationsWithPayload({
collection: 'posts',
id: post.id,
payload: req.payload,
req,
overrideAccess: false,
})
const ukrainianPost = await getDocumentTranslationWithPayload({
collection: 'posts',
id: post.id,
language: 'uk',
payload: req.payload,
req,
overrideAccess: false,
})
const settings = await findGlobalByLanguageWithPayload({
slug: 'site-settings',
language: 'uk',
payload: req.payload,
req,
overrideAccess: false,
})
await updateGlobalByLanguageWithPayload({
slug: 'site-settings',
language: 'uk',
payload: req.payload,
req,
overrideAccess: false,
data: {
title: 'Localized title',
},
})For app-level convenience, create your own configured helper module:
import { createMultilangHelpers } from '@roxxel/payload-multilang'
import { getPayload } from 'payload'
import config from '@payload-config'
export const multilang = createMultilangHelpers({
getPayload: () => getPayload({ config }),
})Documentation
Development
The ./dev app uses SQLite. By default it writes dev/payload.dev.sqlite; tests use isolated temporary SQLite files under /tmp.
pnpm install
pnpm run generate:types
pnpm run test:int
pnpm run test:e2e
pnpm run buildLicense
MIT
Notice
This plugin was built entirely by an LLM.
