UNPKG

@intlify/h3

Version:
312 lines (225 loc) β€’ 9.07 kB
<p align="center"> <img alt="logo" width="512" src="./assets/intlify-h3.svg"> </p> <h1 align="center">@intlify/h3</h1> [![npm version][npm-version-src]][npm-version-href] [![npm downloads][npm-downloads-src]][npm-downloads-href] [![CI][ci-src]][ci-href] Internationalization for H3 <!-- eslint-disable markdown/no-missing-label-refs -- NOTE(kazupon): ignore github alert --> > [!NOTE] > You’re viewing the `srvmid` repository, which is developing for H3 v2. If you want to check H3 v1, please see the [`@intlify/h3` repository](https://github.com/intlify/h3/tree/main) <!-- eslint-enable markdown/no-missing-label-refs -- NOTE(kazupon): ignore github alert --> ## 🌟 Features βœ…οΈοΈ &nbsp;**Internationalization utils:** support [internationalization utils](https://github.com/intlify/srvmid/blob/main/packages/h3/docs/index.md) via [@intlify/utils](https://github.com/intlify/utils) βœ…οΈ &nbsp;**Translation:** Simple API like [vue-i18n](https://vue-i18n.intlify.dev/) βœ… &nbsp;**Custom locale detector:** You can implement your own locale detector on server-side ## πŸ’Ώ Installation ```sh # Using npm npm install @intlify/h3 # Using yarn yarn add @intlify/h3 # Using pnpm pnpm add @intlify/h3 # Using bun bun add @intlify/h3 ``` ## πŸš€ Usage ### Detect locale with utils Detect locale from `accept-language` header: ```ts import { H3 } from 'h3' import { getHeaderLocale } from '@intlify/h3' const app = new H3() app.get('/', event => { // detect locale from HTTP header which has `Accept-Language: ja,en-US;q=0.7,en;q=0.3` const locale = getHeaderLocale(event.req) return locale.toString() }) ``` Detect locale from URL query: ```ts import { H3 } from 'h3' import { getQueryLocale } from '@intlify/h3' const app = new H3() app.get('/', event => { // detect locale from query which has 'http://localhost:3000?locale=en' const locale = getQueryLocale(event.req) return locale.toString() }) ``` ### Translation If you want to use translation, you need to install `intlify` plugin. As a result, you can use `useTranslation` within the handler: ```ts import { createServer } from 'node:http' import { H3, toNodeListener } from 'h3' import { intlify, detectLocaleFromAcceptLanguageHeader, useTranslation } from '@intlify/h3' // install `intlify` plugin with `H3` constructor const app = new H3({ plugins: [ // configure plugin options intlify({ // detect locale with `accept-language` header locale: detectLocaleFromAcceptLanguageHeader, // resource messages messages: { en: { hello: 'Hello {name}!' }, ja: { hello: 'こんにけは、{name}!' } } // something options // ... }) ] }) app.get('/', async event => { // use `useTranslation` in event handler const t = await useTranslation(event) return t('hello', { name: 'h3' }) }) createServer(toNodeListener(app)).listen(3000) ``` ## πŸ› οΈ Custom locale detection You can detect locale with your custom logic from current `H3Event`. example for detecting locale from url query, and get locale with `getDetectorLocale` util: ```ts import { H3 } from 'h3' import { intlify, getQueryLocale, getDetectorLocale } from '@intlify/h3' import type { H3Event } from 'h3' // define custom locale detector const localeDetector = (event: H3Event): string => { return getQueryLocale(event.req).toString() } const app = new H3({ plugins: [ intlify({ // set your custom locale detector locale: localeDetector // something options // ... }) ] }) app.get('/', async event => { const locale = await getDetectorLocale(event) console.log(`Current Locale: ${locale.language}`) }) ``` You can make that function asynchronous. This is useful when loading resources along with locale detection. <!-- eslint-disable markdown/no-missing-label-refs -- NOTE(kazupon): ignore github alert --> > [!NOTE] > The case which a synchronous function returns a promise is not supported. you need to use `async function`. <!-- eslint-enable markdown/no-missing-label-refs -- NOTE(kazupon): ignore github alert --> ```ts import { H3 } from 'h3' import { intlify, getCookieLocale } from '@intlify/h3' import type { H3Event } from 'h3' import type { DefineLocaleMessage, CoreContext } from '@intlify/h3' const loader = (path: string) => import(path).then(m => m.default) const messages: Record<string, () => ReturnType<typeof loader>> = { en: () => loader('./locales/en.json'), ja: () => loader('./locales/ja.json') } // define custom locale detector and lazy loading const localeDetector = async ( event: H3Event, intlify: CoreContext<string, DefineLocaleMessage> ): Promise<string> => { // detect locale const locale = getCookieLocale(event.req).toString() // resource lazy loading const loader = messages[locale] if (loader && !intlify.messages[locale]) { const message = await loader() intlify.messages[locale] = message } return locale } const app = new H3({ plugins: [ intlify({ // set your custom locale detector locale: localeDetector // something options // ... }) ] }) ``` ## πŸ–ŒοΈ Resource keys completion <!-- eslint-disable markdown/no-missing-label-refs -- NOTE(kazupon): ignore github alert --> > [!NOTE] > Resource Keys completion can be used if you are using [Visual Studio Code](https://code.visualstudio.com/) <!-- eslint-enable markdown/no-missing-label-refs -- NOTE(kazupon): ignore github alert --> You can completion resources key on translation function with `useTranslation`. ![Key Completion](assets/key-completion.gif) resource keys completion has two ways. ### Type parameter for `useTranslation` <!-- eslint-disable markdown/no-missing-label-refs -- NOTE(kazupon): ignore github alert --> > [!NOTE] > The exeample code is [here](https://github.com/intlify/h3/tree/main/playground/local-schema) <!-- eslint-enable markdown/no-missing-label-refs -- NOTE(kazupon): ignore github alert --> You can `useTranslation` set the type parameter to the resource schema you want to key completion of the translation function. the part of example: ```ts app.get('/', async event => { type ResourceSchema = { hello: string } // set resource schema as type parameter const t = await useTranslation<ResourceSchema>(event) // you can completion when you type `t('` return t('hello', { name: 'h3' }) }) ``` ### global resource schema with `declare module '@intlify/h3'` <!-- eslint-disable markdown/no-missing-label-refs -- NOTE(kazupon): ignore github alert --> > [!NOTE] > The exeample code is [here](https://github.com/intlify/h3/tree/main/playground/global-schema) <!-- eslint-enable markdown/no-missing-label-refs -- NOTE(kazupon): ignore github alert --> You can do resource key completion with the translation function using the typescript `declare module`. the part of example: ```ts import en from './locales/en.ts' // 'en' resource is master schema type ResourceSchema = typeof en // you can put the type extending with `declare module` as global resource schema declare module '@intlify/h3' { // extend `DefineLocaleMessage` with `ResourceSchema` export interface DefineLocaleMessage extends ResourceSchema {} } app.get('/', async event => { const t = await useTranslation(event) // you can completion when you type `t('` return t('hello', { name: 'h3' }) }) ``` The advantage of this way is that it is not necessary to specify the resource schema in the `useTranslation` type parameter. ## πŸ› οΈ Utilities & Helpers `@intlify/h3` has a concept of composable utilities & helpers. See the [API References](https://github.com/intlify/srvmid/blob/main/packages/h3/docs/index.md) ## πŸ™Œ Contributing guidelines If you are interested in contributing to `@intlify/h3`, I highly recommend checking out [the contributing guidelines](https://github.com/intlify/srvmid/blob/main/CONTRIBUTING.md) here. You'll find all the relevant information such as [how to make a PR](https://github.com/intlify/srvmid/blob/main/CONTRIBUTING.md#pull-request-guidelines), [how to setup development](https://github.com/intlify/srvmid/blob/main/CONTRIBUTING.md#development-setup)) etc., there. ## 🀝 Sponsors The development of `srvmid` is supported by my OSS sponsors! <p align="center"> <a href="https://cdn.jsdelivr.net/gh/kazupon/sponsors/sponsors.svg"> <img alt="sponsor" src='https://cdn.jsdelivr.net/gh/kazupon/sponsors/sponsors.svg'/> </a> </p> ## ©️ License [MIT](http://opensource.org/licenses/MIT) <!-- Badges --> [npm-version-src]: https://img.shields.io/npm/v/@intlify/h3?style=flat&colorA=18181B&colorB=FFAD33 [npm-version-href]: https://npmjs.com/package/@intlify/h3 [npm-downloads-src]: https://img.shields.io/npm/dm/@intlify/h3?style=flat&colorA=18181B&colorB=FFAD33 [npm-downloads-href]: https://npmjs.com/package/@intlify/h3 [ci-src]: https://github.com/intlify/srvmid/actions/workflows/ci.yml/badge.svg [ci-href]: https://github.com/intlify/srvmid/actions/workflows/ci.yml