@unitex/fluent-compiler
v1.0.3
Published
Compiler from TypeScript to Fluent Translation List (FTL)
Maintainers
Readme
UNITEX Fluent Compiler
Compiler from TypeScript to Fluent Translation List (FTL)
Usage
Define your message lists in default locale:
import { type FluentMessageList, defineFluentMessage as dm, defineFluentMessageListWithPrefix, } from '@unitex/fluent-compiler'; // Message list can be a simple dictionary of strings const messagesEn = { hello: 'Hello World!', welcome: 'Welcome, {$user}!', unreadEmails: dm('{$unreadEmails:plural}', { $unreadEmails: { variants: { other: 'You have {$} unread emails.', // default one: 'You have one unread email.', }, }, }), } as const satisfies FluentMessageList; // Or can have a prefix to make navigation easier const exampleNamespace = 'example_'; const namespacedMessagesEn = defineFluentMessageListWithPrefix( { 'hello': 'Hello Namespace!', '-brand-name': 'My Brand', 'welcome': `Welcome to {${exampleNamespace}-brand-name}.`, 'your-rank': dm('{$pos:number}', { $pos: { params: { type: 'cardinal' }, variants: { 1: 'You finished first!', one: 'You finished {$}st', two: 'You finished {$}nd', few: 'You finished {$}rd', other: 'You finished {$}th', }, defaultVariant: 'other', }, }), } as const satisfies FluentMessageList, exampleNamespace, );Define message lists in the translation locale:
import type { FluentMessageListBasedOn } from '@unitex/fluent-compiler'; const messagesRu = castToReadonly({ hello: 'Привет мир!', welcome: 'Добро пожаловать, {$user}!', unreadEmails: dm('{$unreadEmails:plural}', { $unreadEmails: { variants: { other: 'У вас {$} непрочитанных сообщений.', // default one: 'У вас одно непрочитанное сообщение.', }, }, }), } as const satisfies FluentMessageListBasedOn<typeof messagesEn>);To enable autocompletion you need to provide a message schema by redeclaring
FluentProvidedSchemainterface with your defined message lists (only in default locale):declare module '@unitex/fluent-compiler/fluent_schema' { type CustomMessages = typeof messagesEn & typeof namespacedMessagesEn; interface FluentProvidedSchema extends CustomMessages {} }Compile message lists into
.ftltranslation files:import { compile } from '@unitex/fluent-compiler'; const compiledMessagesEn = compile(messagesEn); fs.writeFileSync('locales/en/messages.ftl', compiledMessagesEn);Use
FluentReaderto get translated messages (it provides simple barebone functionality):// in the Node environment import { FluentReaderBack } from '@unitex/fluent-compiler/back/fluent_reader_back'; // or in the Browser environment import { FluentReaderFront } from '@unitex/fluent-compiler/front/fluent_reader_front'; const reader = new FluentReaderBack({ currentLocaleCode: 'en-GB', defaultLocaleCode: 'en-GB', fallbackLocaleCodes: ['en-US'] supportedLocaleCodes: new Set(['en-GB', 'en-US', 'ru']), translations: new Map([ ['en-GB', ['locales/en-GB/messages.ftl', 'locales/en-GB/namespaced_messages.ftl']], ['en-US', ['locales/en-US/messages.ftl', 'locales/en-US/namespaced_messages.ftl']], ['ru', ['locales/ru/messages.ftl', 'locales/ru/namespaced_messages.ftl']], ]), }); reader.getLocalizedString('welcome', { user: 'John Smith' }); reader.setCurrentLocaleCode('ru'); reader.setFallbackLocaleCodes(undefined); reader.getLocalizedString('welcome', { user: 'Иван Кузнецов' });Optional: write your own
tfunction inspired byFluentReader. See implementation in thesrc/fluent_reader.tsfileOptional: take a look at more example messages at
example/messages.tsfileOptional: learn more about
Project Fluent
Code of Conduct
Contributing
Contributors
Maintainers
Credits
Inspired by WebDevSimplified
intl-crash-course
