{"id":15022371,"url":"https://github.com/t2ym/i18n-element","last_synced_at":"2025-07-24T15:13:26.884Z","repository":{"id":57270339,"uuid":"67899677","full_name":"t2ym/i18n-element","owner":"t2ym","description":"I18N Base Element for Lit and Polymer","archived":false,"fork":false,"pushed_at":"2024-09-29T08:31:55.000Z","size":33716,"stargazers_count":9,"open_issues_count":18,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-16T04:22:21.944Z","etag":null,"topics":["custom-elements","es6","html-template","i18n","lit-element","lit-html","polymer","web-components","webcomponents"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/t2ym.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-10T23:31:28.000Z","updated_at":"2021-09-30T10:13:55.000Z","dependencies_parsed_at":"2024-09-21T12:01:54.678Z","dependency_job_id":"4d595947-5414-416f-92c7-12665994196c","html_url":"https://github.com/t2ym/i18n-element","commit_stats":{"total_commits":1257,"total_committers":1,"mean_commits":1257.0,"dds":0.0,"last_synced_commit":"ac7d4d825aa75e9455a0e52c0f13ac1ca43da167"},"previous_names":[],"tags_count":188,"template":false,"template_full_name":null,"purl":"pkg:github/t2ym/i18n-element","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t2ym%2Fi18n-element","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t2ym%2Fi18n-element/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t2ym%2Fi18n-element/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t2ym%2Fi18n-element/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/t2ym","download_url":"https://codeload.github.com/t2ym/i18n-element/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/t2ym%2Fi18n-element/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262016765,"owners_count":23245572,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["custom-elements","es6","html-template","i18n","lit-element","lit-html","polymer","web-components","webcomponents"],"created_at":"2024-09-24T19:57:51.235Z","updated_at":"2025-07-01T09:04:59.417Z","avatar_url":"https://github.com/t2ym.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/t2ym/i18n-element.svg?branch=master)](https://travis-ci.org/t2ym/i18n-element)\n[![Coverage Status](https://coveralls.io/repos/github/t2ym/i18n-element/badge.svg?branch=master)](https://coveralls.io/github/t2ym/i18n-element?branch=master)\n[![npm](https://img.shields.io/npm/v/i18n-element.svg)](https://www.npmjs.com/package/i18n-element)\n[![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://www.webcomponents.org/element/t2ym/i18n-element)\n\n# i18n-element\n\nI18N Base Element for [`Lit`](https://lit.dev/) and [Polymer](https://polymer-library.polymer-project.org/) with [`i18n-behavior`](https://github.com/t2ym/i18n-behavior) as I18N engine\n\n- `i18n-element` inserts **I18N layer** into UI definitions in HTML templates transparently\n- `i18n-element` comes with the full-featured automation [tools](#Tools)\n\n## Extendable and composable HTML template literals based on `lit-html`\n\n```javascript\nimport { html, i18n, bind } from 'i18n-element/i18n.js';\n\nclass MyI18nElement extends i18n(HTMLElement) {\n  ... // a few boilerplate mandatory methods are omitted here\n  render() {\n    return html`${bind(this, 'my-i18n-element')}\n      \u003cspan\u003elocalizable message with ${this.property}\u003c/span\u003e`;\n  }\n  ...\n}\n\nclass ExtendedElement extends MyI18nElement {\n  render() {\n    return html`${bind(this, 'extended-element')}\n      \u003cdiv\u003eextended message with ${this.property}\u003c/div\u003e\n      ${super.render()}`;\n  }\n}\n\nclass CompositeElement extends i18n(HTMLElement) {\n  render() {\n    return html`${bind(this /* bound to 'composite-element' */)}\n      \u003cdiv\u003ecomposite element with ${getMessage()}\u003c/div\u003e\n      \u003cextended-element\u003e\u003c/extended-element\u003e`;\n  }\n}\n\nconst binding = bind('get-message', import.meta); // bound to a pseudo-element name\n\nconst getMessage = () =\u003e html`${'get-message', binding}\u003cspan\u003eget message\u003c/span\u003e`;\n```\n\n- Each HTML template literal is bound to its **unique** (pseudo-)element name\n- Fetch JSON for locale resources at `locales/{element-name}.{locale}.json`\n\n## Install\n\n```sh\nnpm install i18n-element\n```\n\n## Import\n\n- `lit-html` elements\n\n```javascript\nimport { html, i18n, bind } from 'i18n-element/i18n.js';\n```\n\n- Polymer elements\n```javascript\nimport { Localizable } from 'i18n-element/i18n-element.js';\n```\n\n## Quick Tour\n\n[I18N-ready `pwa-starter-kit`](https://github.com/t2ym/pwa-starter-kit)\n\n```sh\n    npm install -g polymer-cli\n    git clone https://github.com/t2ym/pwa-starter-kit\n    cd pwa-starter-kit\n    npm ci\n    # Add Locales\n    gulp locales --targets=\"de es fr ja zh-Hans\"\n    # I18N Process\n    gulp\n    # Translate XLIFF ./xliff/bundle.*.xlf\n    # Merge Translation\n    gulp\n    # Dev build on http://localhost:8080\n    polymer serve\n    # Static build\n    polymer build\n    # Static build on http://localhost:8080\n    cd build/{esm-unbundled|esm-bundled|es6-bundled|es5-bundled}\n    python -m SimpleHTTPServer 8080\n```\n\n## Syntax\n\n### I18N for `lit-html` elements\n\n- [API Docs](https://t2ym.github.io/i18n-element/)\n- [Demo](https://t2ym.github.io/i18n-element/demo/preprocess/)\n- [Demo Source](https://github.com/t2ym/i18n-element/blob/master/demo/clock/clock.js)\n\n```javascript\nimport { html, i18n, bind } from 'i18n-element/i18n.js';\n\nclass AwesomeElement extends i18n(HTMLElement) {\n  static get importMeta() { return import.meta; }\n  constructor() {\n    super();\n    this.attachShadow({mode: 'open'});\n    this.addEventListener('lang-updated', this._langUpdated.bind(this));\n  }\n  connectedCallback() { this.invalidate(); }\n  _langUpdated(event) { this.invalidate(); }\n  render() {\n    return html`${bind(this, 'awesome-element')}\n      \u003cdiv\u003elocalizable message from ${this.is}\u003c/div\u003e`;\n  }\n  invalidate() {\n    render(this.render(), this.shadowRoot);\n  }\n}\ncustomElements.define('awesome-element', AwesomeElement);\n```\n\n- I18N process automation for [`i18n-element/demo/`](https://github.com/t2ym/i18n-element/blob/master/demo/)\n\n```sh\n    # npm run demo === cd demo; gulp\n    # Add locales\n    npm run demo -- locales --targets=\"de es fr ja zh-Hans\"\n    # I18N process\n    npm run demo\n```\n\n### `Localizable` mixin for Polymer elements\n\n[Demo Source](https://github.com/t2ym/i18n-element/blob/master/demo/poc/elements/localizable-element.js)\n\n```javascript\nimport { LegacyElementMixin } from '@polymer/polymer/lib/legacy/legacy-element-mixin.js';\nimport { html } from '@polymer/polymer/lib/utils/html-tag.js';\n\nimport { Localizable } from 'i18n-element/i18n-element.js';\n\nclass LocalizableElement extends Localizable(LegacyElementMixin(HTMLElement)) {\n  static get importMeta() { return import.meta; }\n  static get template() {\n    return html`\u003cspan id=\"label1\"\u003eLocalizable UI label 1\u003c/span\u003e`;\n  }\n  static get is() { return 'localizable-element'; }\n}\ncustomElements.define(LocalizableElement.is, LocalizableElement);\n```\n\n### `Define = class` Thin Definition Syntax\n\n```javascript\nimport 'i18n-element/define-element.js';\n\nDefine = class ThinElement extends Localizable(LegacyElementMixin(HTMLElement)) {\n  static get importMeta() { return import.meta; }\n  static get template() {\n    return html`\u003cspan id=\"label1\"\u003eLocalizable UI label 1\u003c/span\u003e`;\n  }\n  // static get is() can be omitted\n}\n// customElements.define() can be omitted\n```\n\n### I18N-ready Bound Element `i18n-dom-bind` based on Polymer `dom-bind`\n\n```javascript\nimport 'i18n-element/i18n-dom-bind.js';\n```\n\n- Based on Polymer `dom-bind` Element\n- `i18n-dom-bind` element must have `id` attribute\n\n[Demo Source](https://github.com/t2ym/i18n-element/blob/master/demo/poc/index.html)\n\n```html\n\u003ci18n-dom-bind id=\"el5\"\u003e\n  \u003ctemplate\u003e\n    \u003cspan id=\"label1\"\u003eBound UI label 1\u003c/span\u003e\n  \u003c/template\u003e\n\u003c/i18n-dom-bind\u003e\n```\n\n## Tools\n\nFull-featured automation tools are available\n\n| Module        | NPM version | Description |\n|:--------------|:------------|:------------|\n| [gulp-i18n-preprocess](https://github.com/t2ym/gulp-i18n-preprocess) | [![npm](https://img.shields.io/npm/v/gulp-i18n-preprocess.svg)](https://www.npmjs.com/package/gulp-i18n-preprocess) | Build-time I18N preprocessor |\n| [gulp-i18n-leverage](https://github.com/t2ym/gulp-i18n-leverage) | [![npm](https://img.shields.io/npm/v/gulp-i18n-leverage.svg)](https://www.npmjs.com/package/gulp-i18n-leverage) | L10N JSON updater |\n| [gulp-i18n-add-locales](https://github.com/t2ym/gulp-i18n-add-locales) | [![npm](https://img.shields.io/npm/v/gulp-i18n-add-locales.svg)](https://www.npmjs.com/package/gulp-i18n-add-locales) |  L10N JSON placeholder generator |\n| [xliff-conv](https://github.com/t2ym/xliff-conv) | [![npm](https://img.shields.io/npm/v/xliff-conv.svg)](https://www.npmjs.com/package/xliff-conv) | XLIFF/JSON converter |\n| [live-localizer](https://github.com/t2ym/live-localizer) | [![npm](https://img.shields.io/npm/v/live-localizer.svg)](https://www.npmjs.com/package/live-localizer) | L10N widget with Firebase storage |\n| [i18n-element](https://github.com/t2ym/i18n-element) | [![npm](https://img.shields.io/npm/v/i18n-element.svg)](https://www.npmjs.com/package/i18n-element) | I18N base element class |\n| [i18n-behavior](https://github.com/t2ym/i18n-behavior) | [![npm](https://img.shields.io/npm/v/i18n-behavior.svg)](https://www.npmjs.com/package/i18n-behavior) | Run-time I18N handler |\n| [i18n-format](https://github.com/t2ym/i18n-format) | [![npm](https://img.shields.io/npm/v/i18n-format.svg)](https://www.npmjs.com/package/i18n-format) | I18N text formatter |\n| [i18n-number](https://github.com/t2ym/i18n-number) | [![npm](https://img.shields.io/npm/v/i18n-number.svg)](https://www.npmjs.com/package/i18n-number) | I18N number formatter |\n\nThey are fully integrated in these samples:\n\n- [I18N-ready `pwa-starter-kit`](https://github.com/t2ym/pwa-starter-kit) with [`pwa-starter-kit/gulpfile.js`](https://github.com/t2ym/pwa-starter-kit/blob/master/gulpfile.js)\n- [Live Localizer demo](https://github.com/t2ym/live-localizer) with [`live-localizer/demo/gulpfile.js`](https://github.com/t2ym/live-localizer/blob/master/demo/gulpfile.js)\n  - This version is equipped with Firebase configuration and synchronization for `\u003clive-localizer\u003e`\n- [`i18n-element` demo](https://github.com/t2ym/i18n-element) with [`i18n-element/demo/gulpfile.js`](https://github.com/t2ym/i18n-element/blob/master/demo/gulpfile.js)\n  - This is the latest version\n\n### Configurations in `demo/gulpfile.js` - `npm run demo` to trigger I18N automation\n```javascript\n    const useI18nCoreJs = true; // true to use i18n-core.js for preprocessed scripts\n    const useI18nFormatDataProperty = true; // true to proprocess to \u003ci18n-format .data=${data}\u003e\u003cjson-data preprocessed\u003e\n    // Diretories are relative to the current directory\n    var srcDir = 'clock'; // source files directory before preprocessing; should be changed to 'src' or whatever the target project is configured with\n    var tmpDir = 'tmp'; // temporary directory for I18N preprocessing\n    var destDir = 'preprocess'; // directory for preprocessed files\n    const minifyHtmlTemplates = false; // true to minify HTML template literals (experimental)\n    const htmlMinifierOptions = { // options for minification of HTML template literals\n      // Same options as polymer build minify: true\n      collapseWhitespace: true,\n      removeComments: true,\n    };\n    const extractAnonymousTemplates = false; // true For Polymer 3.0 templates\n```\n\n## Compatible Versions\n\n| i18n-element   | i18n-behavior  | Polymer | lit-html |\n|:---------------|:---------------|:--------|:---------|\n| 5.x            | 5.x            | 3.x (optional) | 2.x      |\n| 4.x            | 4.x            | 3.x (optional) | 1.x      |\n| 3.x            | 3.x            | 3.x (mandatory) | 1.x      |\n| 2.x            | 2.x            | 1.x-2.x | -        |\n| -              | 1.x            | 1.x     | -        |\n\n- Polymer elements using `i18n-element.js` must depend on `@polymer/polymer` NPM package themselves\n\n## Browser Compatibility\n\n- TODO: To be updated\n- Polyfilled by `@webcomponents/webcomponentsjs/webcomponents-{bundle|loader}.js`\n\n| Browser   | Chrome  | Firefox  | Edge 13+  | IE 11  | Safari 10+ | Chrome Android  | Mobile Safari  | Opera  |\n|:----------|:-------:|:--------:|:---------:|:------:|:---------:|:---------------:|:--------------:|:------:|\n| Supported | ✔       | ✔        | ✔         | ✔      | ✔         | ✔               | ✔              | ✔      |\n\n## License\n\n[BSD-2-Clause](https://github.com/t2ym/i18n-behavior/blob/master/LICENSE.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ft2ym%2Fi18n-element","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ft2ym%2Fi18n-element","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ft2ym%2Fi18n-element/lists"}