Skip to content

IgorMinar/jsx-i18n-exploration

Repository files navigation

JSX i18n exploration

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.

Getting started

  1. Checkout this repo
  2. pnpm install

Dev mode flow: pnpm dev

Prod mode flow: pnpm build-and-preview

Authoring i18n messages

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.

Example usage

See src/App.tsx for many usage examples.

Even more examples can be found in the test suite: ./jsx$localize/transform.spec.ts

How does it work?

  • Relies on Angular's $localize for all the heavy lifting of message extraction, and runtime as well as build time localization.
  • Uses recast and babel-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.

TODOs

  • 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

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published