Goal: Could internationalization of JSX/TSX templates be as natural as writing JSX itself?
This project attempts to achieve that goal via a JSX pre-processor that can run as a Vite plugin in a way that mimics how Angular's i18n works.
- Checkout this repo
pnpm install
Dev mode flow:
pnpm dev
Prod mode flow:
pnpm build-and-preview
To create a internationalizable message block just add i18n
attribute to any JSX element in the template.
For example instead of
<div>Hello world!</div>
write
<div i18n>Hello world!</div>
or if you want to avoid the extra <div>
wrapper, write just:
<i18n>Hello world!</i18n>
Additionally, you can also internationalize element attributes by adding a matching i18n-<attributeName>
attribute to the element:
<img alt="a cute puppy pic" i18n-alt />
That's it!
To extract the "Hello world!" string, run npm extract-messages
.
The message will be stored in messages.json
file along with its fingerprint.
To translate a newly added message, append the translated message using the same fingerprint key to messages-sk.json
and return pnpm build-and-preview
.
See src/App.tsx for many usage examples.
Even more examples can be found in the test suite: ./jsx$localize/transform.spec.ts
- Relies on Angular's $localize for all the heavy lifting of message extraction, and runtime as well as build time localization.
- Uses
recast
andbabel-ts
parser to parse and mutate JSX/TSX AST while preserving source maps. - Turns all message blocks with interpolation or nested components into an intermediate format which survives translation and message merging, and supports component reordering. This is the format that is extracted by $localized and translated.
- This intermediate format is then turned back to JSX at runtime using a runtime specific
$jsxify
function. - All of this is packaged as Vite plugin so that it can be dropped into any project.
- add support for internationalization of html attributes, e.g.
<img title="a cute puppy pic" i18n-attr-title src="...">
- consider creating
<i18n>
component to enable usage without an existing element wrapper, e.g.<i18n>Hello world!</i18n>
(see disabled tests for more info) - add tests for the
jsxify
function - automate e2e tests
- publish as an npm package
- usage docs
- add support for pluralization via ICUs
- add support for Qwik