About
Documenso uses the following stack to handle translations:
- Lingui (opens in a new tab) - React i10n library
- Crowdin (opens in a new tab) - Handles syncing translations
- OpenAI (opens in a new tab) - Provides AI translations
Additional reading can be found in the Lingui documentation (opens in a new tab).
Requirements
You must insert setupI18nSSR()
when creating any of the following files:
- Server layout.tsx
- Server page.tsx
- Server loading.tsx
Server meaning it does not have 'use client'
in it.
import { setupI18nSSR } from '@documenso/lib/client-only/providers/i18n.server';
export default function SomePage() {
setupI18nSSR(); // Required if there are translations within the page, or nested in components.
// Rest of code...
}
Additional information can be found here. (opens in a new tab)
Quick guide
If you require more in-depth information, please see the Lingui documentation (opens in a new tab).
HTML
Wrap all text to translate in <Trans></Trans>
tags exported from @lingui/macro (not @lingui/react).
<h1>
<Trans>Title</Trans>
</h1>
For text that is broken into elements, but represent a whole sentence, you must wrap it in a Trans tag so ensure the full message is extracted correctly.
<h1>
<Trans>
This is one
<span className="text-foreground/60">full</span>
<a href="https://documenso.com">sentence</a>
</Trans>
</h1>
Constants outside of react components
import { Trans, msg } from '@lingui/macro';
import { useLingui } from '@lingui/react';
// Wrap text in msg`text to translate` when it's in a constant here, or another file/package.
export const CONSTANT_WITH_MSG = {
foo: msg`Hello`,
bar: msg`World`,
};
export const SomeComponent = () => {
const { _ } = useLingui();
return (
<div>
{/* This will render the correct translated text. */}
<p>{_(CONSTANT_WITH_MSG.foo)}</p>
</div>
);
};
Plurals
Lingui provides a Plural component to make it easy. See full documentation here. (opens in a new tab)
// Basic usage.
<Plural one="1 Recipient" other="# Recipients" value={recipients.length} />
Dates
Lingui provides a DateTime instance (opens in a new tab) with the configured locale.
Server components
Note that the i18n instance is coming from setupI18nSSR.
import { Trans } from '@lingui/macro';
import { useLingui } from '@lingui/react';
export const SomeComponent = () => {
const { i18n } = setupI18nSSR();
return <Trans>The current date is {i18n.date(new Date(), { dateStyle: 'short' })}</Trans>;
};
Client components
Note that the i18n instance is coming from the import.
import { i18n } from '@lingui/core';
import { Trans } from '@lingui/macro';
import { useLingui } from '@lingui/react';
export const SomeComponent = () => {
return <Trans>The current date is {i18n.date(new Date(), { dateStyle: 'short' })}</Trans>;
};