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

@kong-ui-public/i18n

v2.1.6

Published

- [Purpose](#purpose) - [TypeScript Support](#typescript-support) - [Global Registration](#global-registration) - [Vue Plugin](#vue-plugin) - [Use in application](#use-in-application) - [Override config while create instance](#override-config-while-

Downloads

17,839

Readme

@kong-ui-public/i18n

Purpose

This is a wrapper around FormatJS that allows consuming application and components to have access to i18n functionality such as:

  • format messages
  • format numbers
  • format dates

TypeScript Support

In order to provide full autocompletion for the translation keys, you need to pass the type of the messages object to the various init functions, as shown here:

Note: For the i18n-t component (Translation.ts), the type checking and auto-completion for the keypath prop are still a work-in-progress due to the issue described here.

Global Registration

// main.ts
import { createI18n, Translation } from '@kong-ui-public/i18n'
import english from './locales/en.json'

const i18n = createI18n<typeof english>('en-us', english, {isGlobal: true})
app.use(Translation.install<typeof english>, { i18n })

// composables/index.ts
import { useI18n } from '@kong-ui-public/i18n'
import english from './locales/en.json'

export default {
  // Be sure to provide the interface when exporting
  useI18n: useI18n<typeof english>,
}

// Component.vue
import composables from './composables'
const i18n = composables.useI18n()

Vue Plugin

import { Translation, createI18n } from '@kong-ui-public/i18n'
import english from './locales/en.json'

const i18n = createI18n<typeof english>('en-us', english, {isGlobal: true})
const app = createApp(App)
app.use(Translation.install<typeof english>, { i18n })

app.mount('#app')

Use in application

When used in application we only need to instantiate Intl object once, during application hydration, and then we can use it anywhere in the app via useI18n composable.

in main.ts (application hydration code):

import { createI18n } from '@kong-ui-public/i18n'
import english from './locales/en.json'

...

// this will create Application instance of Intl object
createI18n<typeof english>('en-us', english, {isGlobal: true})

And then, anywhere in application code where i18n is needed:

<template>
  {{ i18n.t('global.ok') }}
</template>

<script setup lang="ts">
import { useI18n } from '@kong-ui-public/i18n'
import english from './locales/en.json'
const i18n = useI18n<typeof english>()
</script>

Override config while create instance

For some applications there is a need to create Intl instance with config settings overridden. One example of this is when application needs to define error/warning handlers.

Example:

in main.ts (application hydration code):

import { createI18n } from '@kong-ui-public/i18n'
import type { IntlConfigCore } from '@kong-ui-public/i18n'

import english from './locales/en.json'

...

// this will create Application instance of Intl object
createI18n<typeof english>(
    'en-us',
    english,
    {
      onError: (err) {
        console.error(`this is my own i18n errorhandler ${err}`)
      },
      isGlobal: true
    })

and then use i18n as described above.

Third parameter to createI18n could be simple boolean (for backwards compatibility), or IntlConfig object without locale and messages

Use in shared component

When used in shared component (outside of application code), we need Intl that is local to that component, so that it is using component's own localization strings:

<template>
  {{ i18n.t('component.message') }}
</template>


// assuming component is receiving locale code as a property
<script setup lang="ts">
import { createI18n } from '@kong-ui-public/i18n'
import english from '../locales/en.json'

// this will instantiate `Intl` local to this component, using component's english messages.
// TODO: load and pass messages based on language passed from consuming application
const i18n = createI18n<typeof english>(props.locale || 'en-us', english)
</script>

Formatting messages

en.json:

{
  "global": {
    "ok": "Okay"
  },
  "test": {
    "withParams": "Good {dayPart}, My name is {name}!",
    "withPluralization": "{count} {count, plural, =0 {versions} =1 {version} other {versions}} available"
    "withDateTimeFormatting": "{value, date, datetime}",
  }
}

code:

<template>
  Simple formatting:
    {{ i18n.t('global.ok') }}
  With parameters:
    {{ i18n.t('test.withParams', { dayPart: 'Morning', name: 'i18n' }) }}
  With pluralization:
    {{ i18n.t('test.withPluralization', { count: 0 }) }}
    {{ i18n.t('test.withPluralization', { count: 1 }) }}
    {{ i18n.t('test.withPluralization', { count: 11 }) }}
  With datetime formatting
    {{ i18n.t('test.withDateTimeFormatting', { value: Date.parse('Nov 30, 2023, 11:40 AM') }) }}
    {{ i18n.t('test.withDateTimeFormatting', { value: new Date(0).getTime() }) }}
    {{ i18n.t('test.withDateTimeFormatting', { value: 1701344449607 }) }}
</template>


<script setup lang="ts">
import { useI18n } from '@kong-ui-public/i18n'
import english from './locales/en.json'
const i18n = useI18n<typeof english>()
</script>

result:

Simple formatting:
  Okay

With parameters:
  Good Morning, My name is i18n!

With pluralization:
  0 versions available
  1 version available
  11 version available

With datetime formatting:
  Nov 30, 2023, 11:40 AM
  Jan 1, 1970, 12:00 AM 
  Nov 30, 2023, 11:40 AM 

Where is my helpText?

In khcp-ui there are many places where instead of using Intl function we are accessing translations string directly (from the store). Even it is not recommended way of doing thing, but because there are too many places to change, we I18n implementation is supporting this for backwards compatibility.

en.json:

{
    "components": {
        "docUploadCard": {
            "actions": {
                "edit": "Upload New",
                "delete": "Delete"
            }
        }
    }
}

code:

<template>
  {{ helpText.actions.edit }}
</template>


<script setup lang="ts">
import { useI18n } from '@kong-ui-public/i18n'
import english from './locales/en.json'

const i18n = useI18n<typeof english>()
const helpText = i18n.source.components.docUploadCard
</script>

Please, do not use this method in any new code. This prevents using parameters/pluralization and other formatting features. use exposed methods instead.

HTML safe formatting with <i18n-t>

When registered as Vue Plugin

Sometimes it is needed to render translated message with HTML as part of the parameters. For this Provided component can be used.

en.json:

{
  "global": {
    "default": "See the news at {0}. There is a lot there.",
    "named": "{greeting}, my name is {name}. And I am {occupation}. I want {amount}"
  }
}

main.ts (registing component)

import { createI18n, Translation } from '@kong-ui-public/i18n'
import english from './locales/en.json'

...

//this will create Application instance of Intl object
const i18n = createI18n<typeof english>('en-us', english, true)
// this will register <i18n-t> component
app.use(Translation.install<typeof english>, { i18n })

And then, anywhere in application code where i18n is needed

Formatting default slot

code:

<template>
  <i18n-t keypath="global.default">
      <a href="https://google.com">Google</a>
  </i18n-t>
</template>

result:

<span>See the news at <a href="https://google.com">Google</a>. There is a lot there.</span>

Formatting named slots. Using tag to render into template

code:

<template>
    <i18n-t
      tag="h1"
      keypath="global.named"
    >
      <template #greeting>
        <b>Morning</b>
      </template>

      <template #name>
        <i>Val</i>
      </template>

      <template #occupation>
        <i>Money Asker</i>
      </template>

      <template #amount>
        <div class="red">{{ i18n.formatNumber(1000, { style: 'currency', currency: 'USD' }) }}</div>
      </template>
    </i18n-t>
</template>

result:

<h1><b>Morning</b>, my name is <i>Val</i>. And I am <i>Money Asker</i>. I want <div class="red">$1,000.00</div></h1>

With direct use of i18nT component

In some cases we do not have access to the Vue app and cannot relay on registered i18nT plugin. Working on standalone components in public-ui-components is of those cases. And for this your component will look like:

<template>
  <i18n-t
    tag="h1"
    keypath="global.default">
      <a href="https://google.com">Google</a>
  </i18n-t>
</template>

<script setup lang="ts">
  import { createI18n, i18nTComponent } from '@kong-ui-public/i18n'
  import english from './locales/en.json'

  const i18n = createI18n<typeof english>('en-us', english)
  const i18nT = i18nTComponent<typeof english>(i18n)

</script>

Or in old defineComponent way


<template>
  <i18n-t
    :i18n="i18n"
    tag="h1"
    keypath="global.default">
      <a href="https://google.com">Google</a>
  </i18n-t>
</template>


<script lang="ts">
  import { defineComponent } from 'vue'
  import { createI18n, i18nTComponent } from '../src'
  import english from './locales/en.json'

  export default defineComponent({
    components: { i18nT: i18nTComponent<typeof english>() },
    setup() {
      return {
        i18n: createI18n<typeof english>('en-us', english)
      }
    }
  })
</script>

Formatting numbers, dates and times

This comes for free from FormatJS, and documentation on those methods can be found there: FormatJS

You can use ICU Message syntax with FormatJS and they have a description of how you can use this syntax within i18n strings.

This plugin includes an additional datetime formatter (examples above) which uses the same Intl.DateTimeFormatOptions as the below javascript functions for consistency. Date formatting is documented at https://formatjs.io/docs/core-concepts/icu-syntax/#date-type with datetime being an additional format element of the argument:

  • datetime format the date as date and time using the same format as formatIsoDate e.g. Sale begins {start, date, datetime}

In the example Sale begins {start, date, datetime}, start is the value passed into t i.e. t('key.of.string', {start: new Date().toString()}), date is the name of the ICU format we are using, and datetime is to tell FormatJS to use the format we have defined as a standard/common format for formatting 'datetimes'.

Unit tests for I18n wrapper in kong-ui/core also has view examples as a references for those. FormatDate FormatNumber

Every single method listed in FormatJS is exposed and available in i18n wrapper.

Additional service functions.

(as previously exposed by vue18n-n)

formatUnixTimeStamp

Formats a unix timestamp into a formatted date string

code:

const { formatUnixTimeStamp } = useI18n()
console.log(formatUnixTimeStamp('1558006979'))

result:

May 16, 2019, 11:42 AM

formatIsoDate

Format an ISO formatted date

code:

const { formatIsoDate } = useI18n()
console.log(formatIsoDate('2019-05-16T11:42:59.000Z'))

result:

May 16, 2019, 11:42 AM

te

check if translation message exists

en.json

"global": {
  "ok": "Okay"
}

code:

const { te } = useI18n()
console.log({p: te('global.ok'), n: te('global.not.ok')})

result:

{"p": true, "n": false}

tm

returns array values defined for given key

en.json

 "global": {
    "disabled": [
      "You cannot update configurations for services",
      "You cannot accept new developer portal applications",
    ]
  }

code:

const { tm } = useI18n()
console.log(tm('global.disabled'))

result:

[
  "You cannot update configurations for services",
  "You cannot accept new developer portal applications",
]