npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

i18nextify

v3.3.1

Published

enables localization of any page with zero effort

Downloads

1,578

Readme

npm version

i18nextify

Just drop this script on your page and you're ready to deliver your pages in any language.

See the sample (code)!

Checkout this video to see i18nextify in action.

i18nextify uses Virtual DOM to update your page with translations based on the current content. MutationObserver is used to trigger translations on newly added content.

i18nextify comes bundled with i18next.

Should play well with any static or dynamic page not using its own Virtual DOM.

Getting started

The easiest way for guaranteed success is using locizify on locize.com.

Alternatively:

Drop this script on your page.

<!DOCTYPE html>
<html>
  <head>
    <script src="/i18nextify.min.js"></script>
    <!-- or: <script src="https://unpkg.com/i18nextify@^3.2.1"></script> -->
  </head>
  ...
</html>

Optionally you can also define your fallback language directly in the script tag:

<!DOCTYPE html>
<html>
  <head>
    <script src="/i18nextify.min.js" id="i18nextify" fallbacklng="en"></script>
    <!-- or: <script src="https://unpkg.com/i18nextify@^3.2.1" id="i18nextify" fallbacklng="en"></script> -->
  </head>
  ...
</html>

Request your page with querystring params ?debug=true&saveMissing=true and open the browser console to see i18nextify in action. It will output all missing translations - start serving them from /locales/{{lng}}/translation.json.

See the example for details.

Initialize with options

<!DOCTYPE html>
<html>
  <head>
    <script src="/i18nextify.min.js"></script>
    <script>
      window.i18nextify.init({
        // defaults that are set
        autorun: true, // setting to false init will return an object with start function
        ele: document.body, // pass in another element if you like to translate another html element
        ignoreTags: ['SCRIPT'], // tags to ignore

        // using keys instead of content as keys
        keyAttr: 'i18next-key', // node attribute to use as key
        ignoreWithoutKey: false, // set to true to only support nodes having a key

        // per default not set
        ignoreIds: ['ignoreMeId'],
        ignoreClasses: ['ignoreMeClass'],

        // attributes to translate
        translateAttributes: ['placeholder', 'title', 'alt', 'value#input.type=button', 'value#input.type=submit'],

        // merging content (eg. a tags in p tags)
        mergeTags: [], // tags to merge innerHtml to one key
        inlineTags: [], // tags to inline (eg. a, span, abbr, ...)
        ignoreInlineOn: [], // tags to ignore inlining tags under inlineTags

        // cleanup for keys
        cleanIndent: true, // removes indent, eg. if a p tag spans multiple lines
        ignoreCleanIndentFor: ['PRE', 'CODE'], // ignores cleaning up of indent for those tags needing that extra spaceing
        cleanWhitespace: true, // removes surrounding whitespace from key

        namespace: false, // set a filename - default namespace will be translation
        namespaceFromPath: false // set true will use namepace based on window.location.pathname
        ns: ['common'] // -> only set if accessing more then one namepace

        // + all options available in i18next
      });
    </script>
  </head>
  ...
</html>

Delay initial translation

const translation = i18nextify.init({
  autorun: false,
});

setTimeout(function () {
  translation.start();
}, 1000);

Merge content / using html in translations

Just set translated attribute:

<p merge>
  all inside will be used as on segment, even if having other
  <a>elements inside</a>
</p>

// key = all inside will be used as on segment, even if having other
<a>elements inside</a>

Same could be done using options:

mergeTags: [], // tags to merge innerHtml to one key
inlineTags: [], // tags to inline (eg. a, span, abbr, ...)
ignoreInlineOn: [], // tags to ignore inlining tags under inlineTags

Fragment replacement for links and images

<img src="/images/{{a.png}}" alt="big A" />

You will find a.png to be a key in your translation files - it's value can be replaced to eg. a-de.png for German (all other languages will fallback to a.png)

<a href="/{{statistic}}">Open my statistics</a>

statistic will be a regular key that can be translated. But be aware you will need to provide that routes - eg. using localized routes on the server

Avoid translating

an element

Just set translated attribute:

<div translated>this won't get translated - nor this elements children</div>

By ignoring tag, class, id

Just add needed items to the specific array:

window.i18nextify.init({
  ignoreTags: ['SCRIPT'], // need to be uppercased
  ignoreIds: ['ignoreMeId'],
  ignoreClasses: ['ignoreMeClass']
});
<script>
  // this won't get translated - nor this elements children
</script>
<div id="ignoreMeId">
  this won't get translated - nor this elements children
</div>
<div class="ignoreMeClass">
  this won't get translated - nor this elements children
</div>

Just add translated-attribute

Translating an element with options

For extended translations like plurals, interpolation, ... you need to add options to the element

<div i18next-options='{"foo": "bar"}'>
  foo {{bar}}
  <p i18next-options='{"foo2": "bar2"}'>foo {{foo}}; foo2 {{foo2}}</p>
</div>

Translating JavaScript code

You can use the i18next instance used to provide the translation functionality directly. Just make sure the instance is initialized already:

<script>
  // use t function of i18next
  // https://www.i18next.com/translation-function/essentials
  function useI18next() {
    var translated = i18nextify.i18next.t('some key');
  }

  if (i18nextify.i18next.isInitialized) {
    useI18next();
  } else {
    i18nextify.i18next.on('initialized', function(options) {
      useI18next();
    })
  }
</script>

Options get inherited from parent to child nodes.

Set different namespaces

Default would be translation.

Set a different one:

window.i18nextify.init({
  namespace: 'myNamespace'
});

autogenerate one per route:

window.i18nextify.init({
  namespaceFromPath: true
});

Access different namespaces

This is useful for reused elements that are on every page, eg. like footer,... and you're using namespaceFromPath. So you can avoid having that segments on every routes namespace file.

window.i18nextify.init({
  namespace: 'translation', // -> set the default namespace
  ns: ['common'] // -> add additional namespaces to load
});
<div i18next-options='{"ns": "common"}'>
  <p>different namespace: i18next-options='{"ns": "common"}'</p>
  <p>
    set it on i18next options and assert to add it to
    <strong>i18next.options.ns array on init</strong>
  </p>
</div>

Avoid flickering on initial load

<!DOCTYPE html>
<html>
  <head>
    <script src="/i18nextify.min.js"></script>
  </head>
  <body style="display: none">
    ...
  </body>
</html>

Just set the element style display to none. i18nextify will change it to block when ready.

Change File to use

You can change the namespace after loading to some other file (eg. before transitioning to another page).

window.i18nextify.changeNamespace('newNamespace');

force a retranslation:

window.i18nextify.forceRerender();