Skip to content

Commit 08b3140

Browse files
authored
Merge pull request #53 from PolymerLabs/more-readme
Expand README
2 parents a4e3fef + c933c96 commit 08b3140

File tree

1 file changed

+189
-7
lines changed

1 file changed

+189
-7
lines changed

README.md

+189-7
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
<img src="./rgb_lit.png" width="150" height="100" align="right"></img>
66

7-
###### [API](#api) | [Tutorial](#tutorial) | [API](#api)
7+
###### [Features](#features) | [Overview](#overview) | [Modes](#modes) | [Tutorial](#tutorial) | [API](#api) | [Status event](#lit-localize-status-event) | [Localized mixin](#localized-mixin) | [CLI](#cli) | [Config file](#config-file) | [FAQ](#faq)
88

9-
> lit-localize is a library and command-line tool for localizing/translating web
9+
> lit-localize is a library and command-line tool for localizing web
1010
> applications that are based on lit-html and LitElement.
1111
1212
## Features
@@ -18,6 +18,64 @@
1818
- 🆓 Generate a zero-overhead bundle for each locale
1919
- 🔁 ... or dynamically load locales and automatically re-render
2020

21+
## Overview
22+
23+
Wrap your template with the `msg` function to make it localizable:
24+
25+
```typescript
26+
import {html} from 'lit-html';
27+
import {msg} from 'lit-localize';
28+
render(msg('greeting', html`Hello <b>World</b>!`), document.body);
29+
```
30+
31+
Run `lit-localize` to extract all localizable templates and generate an XLIFF
32+
file, a format which is supported by many localization tools and services:
33+
34+
```xml
35+
<trans-unit id="greeting">
36+
<source>Hello <ph id="0">&lt;b></ph>World<ph id="1">&lt;/b></ph>!</source>
37+
<!-- target tag added by your localization process -->
38+
<target>Hola <ph id="0">&lt;b></ph>Mundo<ph id="1">&lt;/b></ph>!</target>
39+
</trans-unit>
40+
```
41+
42+
Use _transform_ mode to generate an optimized bundle for each locale:
43+
44+
```javascript
45+
import {html} from 'lit-html';
46+
render(html`Hola <b>Mundo</b>!`, document.body);
47+
```
48+
49+
Alternatively, use _runtime_ mode to dynamically switch locales without a page
50+
reload:
51+
52+
```typescript
53+
import {configureLocalization} from 'lit-localize';
54+
55+
const {setLocale} = configureLocalization({
56+
sourceLocale: 'en',
57+
targetLocales: ['es-419', 'zh_CN'],
58+
loadLocale: (locale) => import(`/locales/${locale}.js`),
59+
});
60+
61+
(async () => {
62+
await setLocale('es-419');
63+
renderApplication();
64+
})();
65+
```
66+
67+
## Modes
68+
69+
lit-localize supports two output modes: _transform_ and _runtime_.
70+
71+
| | Transform mode | Runtime mode |
72+
| ------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
73+
| Output | A full build of your application for each locale, with all `msg` calls replaced with static localized templates. | A dynamically loadable template module for each target locale. |
74+
| Make template localizable | `msg()` | `msg()` |
75+
| Configure | `const {getLocale, setLocale} =`<br>`configureLocalization(...);` | (Optional)<br><br> `const {getLocale} =`<br>`configureTransformLocalization(...);` |
76+
| Switch locales | Refresh page and load a different `.js` file | Call `setLocale()` and re-render using any of:<br><br>- `lit-localize-status` event<br>- `setLocale` promise<br>- `Localized` mixin for `LitElement` |
77+
| Advantages | - Fastest rendering<br>- Fewer bytes for a single locale | - Faster locale switching<br>- Fewer _marginal_ bytes when switching locales |
78+
2179
## Tutorial
2280

2381
1. Install lit-localize. You get both a client library and a command-line tool.
@@ -234,9 +292,10 @@ Return the active locale code.
234292

235293
### `setLocale(locale: string) => Promise`
236294

237-
Set the active locale code, and begin loading templates for that locale using
238-
the `loadLocale` function that was passed to `configureLocalization`. Returns a
239-
promise that resolves when the next locale is ready to be rendered.
295+
Available only in runtime mode. Set the active locale code, and begin loading
296+
templates for that locale using the `loadLocale` function that was passed to
297+
`configureLocalization`. Returns a promise that resolves when the next locale is
298+
ready to be rendered.
240299

241300
Note that if a second call to `setLocale` is made while the first requested
242301
locale is still loading, then the second call takes precedence, and the promise
@@ -298,7 +357,7 @@ html`Hola <b>${getUsername()}!</b>`;
298357

299358
### `LOCALE_STATUS_EVENT`
300359

301-
Name of the [`lit-localize-status` event](#lit-localize-status-event).
360+
Name of the [`lit-localize-status`](#lit-localize-status-event) event.
302361

303362
## `lit-localize-status` event
304363

@@ -375,7 +434,7 @@ If you are using [LitElement](https://lit-element.polymer-project.org/), then
375434
you can use the `Localized`
376435
[mixin](https://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/)
377436
from `lit-localize/localized-element.js` to ensure that your elements
378-
automatically re-render whenever the locale changes.
437+
automatically re-render whenever the locale changes in runtime mode.
379438

380439
```typescript
381440
import {Localized} from 'lit-localize/localized-element.js';
@@ -394,3 +453,126 @@ class MyElement extends Localized(LitElement) {
394453
```
395454

396455
In transform mode, applications of the `Localized` mixin are removed.
456+
457+
## CLI
458+
459+
Running the `lit-localize` command-line program does the following:
460+
461+
1. Reads your [config file](#config-file) according to the `--config` flag.
462+
463+
2. Analyzes all TypeScript files covered by your `tsconfig.json`, and discovers
464+
all calls to the lit-localize `msg` function.
465+
466+
3. Creates or updates an XLIFF (`.xlf`) file for each of your target locales,
467+
with a `<source>` tag corresponding to each `msg` call.
468+
469+
4. Reads existing `<target>` tags from existing XLIFF files for each `msg` call.
470+
471+
5. When in _transform_ mode, compiles your TypeScript project for each locale,
472+
where all `msg` calls are replaced with the corresponding static, localized
473+
version from that locale's XLIFF file.
474+
475+
6. When in _runtime_ mode, generates a `<locale>.ts` file for each locale, which
476+
can be dynamically loaded by the `lit-localize` module.
477+
478+
It takes the following flags:
479+
480+
| Flag | Description |
481+
| ---------- | --------------------------------------------------------------------------- |
482+
| `--help` | Display this list of flags. |
483+
| `--config` | Path to JSON [config file](#config-file). Defaults to `./lit-localize.json` |
484+
485+
## Config file
486+
487+
| Property | Type | Description |
488+
| ---------------------------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
489+
| `sourceLocale` | `string` | Required locale code that templates in the source code are written in. |
490+
| `targetLocales` | `string[]` | Required locale codes that templates will be localized to. |
491+
| `tsConfig` | `string` | Path to a `tsconfig.json` file that describes the TypeScript source files from which messages will be extracted. |
492+
| `output.mode` | `"transform"`, `"runtime"` | What kind of output should be produced. See [modes](#modes). |
493+
| `interchange.format` | `"xliff"`, `"xlb"` | Data format to be consumed by your localization process. Options:<br><br>- `"xliff"`: [XLIFF 1.2](http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html) XML format<br>- `"xlb"`: Google-internal XML format |
494+
| <h4 colspan="3">Transform mode only</h4> |
495+
| `output.outputDir` | `string` | Output directory for generated TypeScript modules. Into this directory will be generated a `<locale>.ts` for each `targetLocale`, each a TypeScript module that exports the translations in that locale keyed by message ID. |
496+
| <h4 colspan="3">XLIFF only</h4> | |
497+
| `interchange.xliffDir` | `string` | Directory on disk to read/write `.xlf` XML files. For each target locale, the file path `"<xliffDir>/<locale>.xlf"` will be used. |
498+
499+
## FAQ
500+
501+
- [How should I set the initial locale in transform mode?](#how-should-i-set-the-initial-locale-in-transform-mode)
502+
- [How should I switch locales in transform mode?](#how-should-i-switch-locales-in-transform-mode)
503+
504+
### How should I set the initial locale in transform mode?
505+
506+
In transform mode, the locale is determined simply by the JavaScript bundle you
507+
load. How you determine which bundle to load when your page loads is up to you.
508+
509+
> IMPORTANT: Take care to always validate your locale codes when dynamically
510+
> choosing a script name! The example below is safe because a script can only be
511+
> loaded if it matches one of the fixed locale codes in the regular expression,
512+
> but if our matching logic was less precise, it could result in bugs or attacks
513+
> that inject insecure JavaScript.
514+
515+
For example, if your application's locale is reflected in the URL, you can
516+
include an inline script in your HTML file that checks the URL and inserts the
517+
appropriate `<script>` tag:
518+
519+
```html
520+
<!DOCTYPE html>
521+
<script>
522+
// If the subdomain matches one of our locale codes, load that bundle.
523+
// Otherwise, load the default locale bundle.
524+
//
525+
// E.g. https://es-419.example.com/
526+
// ^^^^^^
527+
const match = window.location.href.match(
528+
/^https?:\/\/(es-419|zh_CN|en|es)\./
529+
);
530+
const locale = match ? match[1] : 'en';
531+
const script = document.createElement('script');
532+
script.type = 'module';
533+
script.src = `/${locale}.js`;
534+
document.head.appendChild(script);
535+
</script>
536+
```
537+
538+
Implementing logic similar to this on your _server_ so that the appropriate
539+
script tag is statically rendered into your HTML file will usually result in the
540+
best performance, because the browser will start downloading your script as
541+
early as possible.
542+
543+
### How should I switch locales in transform mode?
544+
545+
In transform mode, the `setLocale` function is not available. Instead, reload
546+
the page so that the next load will pick a different locale bundle.
547+
548+
For example, this `locale-picker` custom element loads a new subdomain whenever
549+
a new locale is selected from a drop-down list:
550+
551+
```typescript
552+
import {LitElement} from 'lit-element';
553+
554+
const locales = ['es-419', 'zh_CN', 'en', 'es'];
555+
556+
class LocalePicker extends LitElement {
557+
render() {
558+
return html`
559+
<select @change=${this.localeChanged}>
560+
${locales.map(
561+
(locale) => html`<option value="${locale}">${locale}</option>`
562+
)}
563+
</select>
564+
`;
565+
}
566+
567+
localeChanged(event: Event) {
568+
const newLocale = event.target.value;
569+
const newHostname = `${newLocale}.example.com`;
570+
const url = new URL(window.location);
571+
if (newHostname !== url.hostname) {
572+
url.hostname = newHostname;
573+
window.location.assign(url);
574+
}
575+
}
576+
}
577+
customElements.define('locale-picker', LocalePicker);
578+
```

0 commit comments

Comments
 (0)