Messages and catalogs
Shipped UI catalogs, project overrides and next-intl integration.
On this page
Systhema ships reviewed English, Hungarian, French, Dutch, Czech, Slovak, and Arabic catalogs, with one JSON file per language under the package's messages/ source. English is the source catalog; the parity test requires every translation to have exactly the same paths and ICU arguments, which makes each language file suitable for review by a professional translator. Systhema does not ship languages that have not been grammatically reviewed.
Project catalogsLink to this section
Every configured locale without a shipped catalog must register a complete project catalog, which prevents accidental English UI on a translated route. Put those catalogs directly in systhema.config.ts's messages.catalogs — there is no generated seam to write them into; SysthemaPage reads the config at request time and resolves the merged catalog for the active locale itself. Project messages extend the built-in catalog for a shipped locale, and all non-Systhema namespaces are preserved for the project's own next-intl use.
const config: SysthemaConfig = {
locales: defineSysthemaLocales({ supported: ['en', 'fr'], default: 'en' }),
messages: { catalogs: { fr: frenchMessages } },
// Or make the fallback intentional: messages: { fallback: 'en' }
}Message helpersLink to this section
getSysthemaMessages(), mergeSysthemaMessages(), createSysthemaFrontendTranslator(), the catalog types, and the typed message key union are available from the locale-off-safe @systhemaui/next/messages entry. It includes the small ICU formatter Systhema uses when locales are off; that entry does not import next-intl. The published ESM entry imports its shipped JSON catalogs with standard JSON import attributes, so it can be loaded directly by supported Node.js ESM runtimes as well as by Next.js bundlers. Client components can use the equally isolated provider and hook:
'use client'
import { useSysthemaFrontendTranslator } from '@systhemaui/next/messages/client'
export function ProjectSearch() {
const { t } = useSysthemaFrontendTranslator()
return <input aria-label={t('posts.searchPlaceholder')} />
}Translating your own componentsLink to this section
Consumer collections, blocks, and custom templates should accept the generated locale and frontendMessages props. On the server, call createSysthemaFrontendTranslator(locale, frontendMessages); in a client child, use the hook above. Low-level React components remain framework-neutral and accept labels props, while Systhema's Next/Payload adapters fill those props from the active catalog. A partial Systhema override is allowed for any shipped locale (en, hu, fr, nl, cs, sk, ar); an unshipped locale requires the complete namespace unless messages.fallback: 'en' is explicitly configured.
Frontend locales/messages and Payload Admin translations are deliberately independent. A site can publish French, Dutch, and English while its Admin is English-only, or publish only Hungarian while its Admin offers English and Hungarian. See Admin translations.