Type-safe internationalization (i18n) for Next.js

Overview


Type-safe internationalization (i18n) for Next.js


Features

  • 100% Type-safe: Locales in TS or JSON, type-safe t() & scopedT(), type-safe params
  • Small: 1.2 KB gzipped (1.7 KB uncompressed), no dependencies
  • Simple: No webpack configuration, no CLI, just pure TypeScript
  • SSR: Load only the required locale, SSRed

Usage

pnpm install next-international
  1. Make sure that you've followed Next.js Internationalized Routing, and that strict is set to true in your tsconfig.json

  2. Create locales/index.ts with your locales:

import { createI18n } from 'next-international'
import type Locale from './en'

export const {
  useI18n,
  I18nProvider,
  getLocaleStaticProps,
} = createI18n<typeof Locale>({
  en: () => import('./en'),
  fr: () => import('./fr'),
});

Each locale file should export a default object (don't forget as const):

// locales/en.ts
export default {
  'hello': 'Hello',
  'welcome': 'Hello {name}!',
} as const
  1. Wrap your whole app with I18nProvider inside _app.tsx:
// pages/app.tsx
import { I18nProvider } from '../locales'

function App({ Component, pageProps }) {
  return (
    <I18nProvider locale={pageProps.locale}>
      <Component {...pageProps} />
    </I18nProvider>
  )
}
  1. Add getLocaleStaticProps to your pages, or wrap your existing getStaticProps (this will allows SSR locales, see Load initial locales client-side if you want to load the initial locale client-side):
// locales/index.tsx
export const getStaticProps = getLocaleStaticProps()

// or with an existing `getStaticProps` function:
export const getStaticProps = getLocaleStaticProps((ctx) => {
  // your existing code
  return {
    ...
  }
})
  1. Use useI18n:
import { useI18n } from '../locales'

function App() {
  const { t } = useI18n()
  return (
    <div>
      <p>{t('hello')}</p>
      <p>{t('welcome', { name: 'John' })}</p>
    </div>
  )
}

Examples

Scoped translations

When you have a lot of keys, you may notice in a file that you always use and such duplicate the same scope:

// We always repeat `pages.settings`
t('pages.settings.title')
t('pages.settings.description', { identifier })
t('pages.settings.cta')

We can avoid this using scoped translations with the scopedT function from useI18n:

const { scopedT } = useI18n()
const t = scopedT('pages.settings')

t('title')
t('description', { identifier })
t('ct')

And of course, the scoped key, subsequents keys and params will still be 100% type-safe.

Change current locale

Export useChangeLocale from createI18n:

// locales/index.ts
export const {
  useChangeLocale,
  ...
} = createI18n({
  ...
});

Then use this as a hook:

import { useChangeLocale } from '../locales'

function App() {
  const changeLocale = useChangeLocale()

  return (
    <button onClick={() => changeLocale('en')}>English</button>
    <button onClick={() => changeLocale('fr')}>French</button>
  )
}

Use JSON files instead of TS for locales

Currently, this breaks the parameters type-safety, so we recommend using the TS syntax. See this issue: microsoft/TypeScript#32063.

You can still get type-safety by explicitly typing the locales

// locales/index.ts
import { createI18n } from 'next-international'
import type Locale from './en.json'

export const {
  useI18n,
  I18nProvider,
  getLocaleStaticProps,
} = createI18n<typeof Locale>({
  en: () => import('./en.json'),
  fr: () => import('./fr.json'),
});

Explicitly typing the locales

If you want to explicitly type the locale, you can create an interface that extends BaseLocale and use it as the generic in createI18n:

// locales/index.ts
import { createI18n, BaseLocale } from 'next-international'

interface Locale extends BaseLocale {
  'hello': string
  'welcome': string
}

export const {
  ...
} = createI18n<Locale>({
  en: () => import('./en.json'),
  fr: () => import('./fr.json'),
});

Load initial locales client-side

Warning: This should not be used unless you know what you're doing and what that implies.

If for x reason you don't want to SSR the initial locale, you can load it on the client. Simply remove the getLocaleStaticProps from your pages.

You can also provide a fallback component while waiting for the initial locale to load inside I18nProvider:

<I18nProvider locale={pageProps.locale} fallback={<p>Loading locales...</p>}>
  ...
</I18nProvider>

Type-safety on locales files

Using defineLocale, you can make sure all your locale files implements all the keys of the base locale:

// locales/index.ts
export const {
  defineLocale
  ...
} = createI18n({
  ...
});

It's a simple wrapper function around other locales:

// locales/fr.ts
export default defineLocale({
  'hello': 'Bonjour',
  'welcome': 'Bonjour {name}!',
})

License

MIT

Comments
  • error - SerializableError: Error serializing `.locale[

    error - SerializableError: Error serializing `.locale["pages.past.date"]` returned from `getServerSideProps` in "/".

    Hey,

    i'm currently creating a simple example to test the new blitz toolkit.

    At the same time I want to test your i18n package.

    Everything seems to work, but since I added the language switcher and refreshed the page after changing the language from "en" (=default) to "de" I get the following error:

    error - SerializableError: Error serializing `.locale["pages.past.date"]` returned from `getServerSideProps` in "/".
    Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.
        at isSerializable (<local_path>/node_modules/next/dist/lib/is-serializable-props.js:36:19)
        at <local_path>/node_modules/next/dist/lib/is-serializable-props.js:43:66
        at Array.every (<anonymous>)
        at isSerializable (<local_path>/node_modules/next/dist/lib/is-serializable-props.js:40:39)
        at <local_path>/node_modules/next/dist/lib/is-serializable-props.js:43:66
        at Array.every (<anonymous>)
        at isSerializable (<local_path>/node_modules/next/dist/lib/is-serializable-props.js:40:39)
        at Object.isSerializableProps (<local_path>/node_modules/next/dist/lib/is-serializable-props.js:63:12)
        at Object.renderToHTML (<local_path>/node_modules/next/dist/server/render.js:552:67)
        at processTicksAndRejections (node:internal/process/task_queues:96:5) {
      page: '/'
    }
    

    To be honest, I'm not sure if this is a problem with your package.

    You can find the complete source here: https://github.com/noxify/blitz-hackernews


    Steps to reproduce:

    1. Install the app
    2. Start the dev server via npm run dev
    3. Open the browser and go to page http://localhost:3000
      • You will see the index page and the language is english
    4. Switch the language to de (=german) ( via the icon in the header navigation )
      • You will see that the language has been changed to german
    5. Reload the page
      • You will see the error

    Please let me know in case you need additional information or something else.

    opened by noxify 10
  • Error: Uncaught [Error: `useI18n` must be used inside `I18nProvider`]

    Error: Uncaught [Error: `useI18n` must be used inside `I18nProvider`]

    Hello, thank you for this awesome library I'm using this package with Jest and it doesn't seems to work properly

    this is my customRender.tsx

    import en from 'locales/en';
    import { ThemeProvider } from '@mui/material';
    import { theme } from 'styles/theme';
    import { render, cleanup } from '@testing-library/react';
    import { createI18n } from 'next-international';
    
    // I tried different methods to mock next/router
    // 1. first attempt
    const useRouter = jest.spyOn(require('next/router'), 'useRouter');
    useRouter.mockImplementationOnce(() => ({
        locale: 'en',
        defaultLocale: 'en',
        locales: ['en', 'fr'],
    }));
    
    // 2. second attempt
    jest.mock('next/router', () => ({
      useRouter: () => ({
        locale: 'en',
        defaultLocale: 'en',
        locales: ['en', 'fr'],
      }),
    }));
    
    afterEach(() => {
        cleanup()
    })
    
    const { I18nProvider } = createI18n<typeof en>({
        en: () => import('locales/en'),
        fr: () => import('locales/fr'),
    })
    
    const Providers = ({ children }: { children: any }) => {
        return <I18nProvider locale={en}><ThemeProvider theme={theme}>{children}</ThemeProvider></I18nProvider>
    };
    const customRender = (ui: any, options = {}) => render(ui, { wrapper: Providers, ...options });
    export * from '@testing-library/react';
    export { default as userEvent } from '@testing-library/user-event'
    export { customRender as render };
    

    I have a component where I use i18n and the test fail all the time

    import { cleanup, fireEvent } from '@testing-library/react';
    import { render, screen } from 'testing/customRender'
    
    import React from 'react';
    import InputField from '.';
    
    afterEach(cleanup);
    
    describe('<InputField />', () => {
        it('handleChange function called', () => {
            const spy = jest.fn();
            render(<InputField field={{ name: 'text', onChange: spy }} label="nom" />);
            let input = screen.getByLabelText('nom') as HTMLInputElement;
            expect(input.value).toBe('');
    
            fireEvent.change(input, { target: { value: '23' } });
            fireEvent.blur(input, { target: { value: '23' } });
            expect(spy).toHaveBeenCalledTimes(1);
        });
    });
    
    // locales.ts
    import { createI18n } from 'next-international';
    import type Locale from './en';
    export const { useI18n, I18nProvider, useChangeLocale, defineLocale, getLocaleProps } = createI18n<typeof Locale>({
      en: () => import('./en'),
      fr: () => import('./fr'),
    });
    

    Inside my component I import the hook use18n() from locales const { t } = useI18n();

    When I run my tests I get the following error

    TypeError: Cannot destructure property 'locale' of '(0 , B.useRouter)(...)' as it is null.

    Can you please provide an example with jest? a wrapper and how to use it inside a component that uses i18n

    Thank you so much

    opened by chaosLegacy 8
  • feat: implement react translation functions

    feat: implement react translation functions

    We are through the process of adding internationalization to our application and found the existing functions (t and scopedT) to be limiting as they only allowed parameters to be strings.

    This pull request implements rt and scopedRT which allow parameters to be react components like <strong>John</strong>

    This was just quickly put together, so I'm open to changing anything!

    I didn't know where to put the type ReactParamsObject (as international-types doesn't depend on React, and shouldn't - as it is more generic that way) so I put it in create-use-i18n - help appreciated is on where it should actually be!

    opened by EXio4 7
  • Export `Locale` types to create custom `Locale` interface

    Export `Locale` types to create custom `Locale` interface

    Currently the recommended practice is to create a locale as const, export it, import it as a type & use it for the createI18n generic.

    In future to change all other types you need to change that objects structure to change the type which doesn't seem right.

    My proposal to make this better is to add the Locale & LocaleValue types in types.ts to the root export such that you can create a general purpose interface or type to manage your locales.

    Example

    // locales/index.ts
    import { createI18n } from 'next-international';
    
    import type { Locale as BaseLocale } from 'next-international';
    
    interface MyCustomLocale extends BaseLocale {
      hello: string;
    }
    
    export const {
      defineLocale,
      useI18n,
      // ...
    } = createI18n<MyCustomLocale>({
      en: () => import('./en'),
    });
    
    // locales/en.ts
    import { defineLocale } from '.';
    
    export default defineLocale({
      hello: 'Hello',
    })
    
    opened by NuroDev 7
  • Example usage with tests.

    Example usage with tests.

    Hello! Been using this library for a while but I'm having a bit of a catch up when trying to make unit tests with it.

    On regular i18n I either mock the tests or pass a default locale to use with it. But in this case due to passing props using Next.js pageProps I'm running into some issues.

    Here are the few pieces of code I'm currently using to implement my tests.

    import { createI18n } from "next-international";
    import Locale from "../../locales/en";
    
    const TestWrapper = ({ children }: { children: JSX.Element }) => {
      const { I18nProvider } = createI18n<typeof Locale>({
        en: () => import("../../locales/en"),
      });
     
      return (
          <I18nProvider locale={Locale}>
             {children}
          </I18nProvider>
      );
    };
     
    export default TestWrapper;
    

    And then I wrap a component with it.

    import { render, screen, waitFor } from "@testing-library/react";
    import TestWraper from "../utils/testWraper";
    import HomePage from "../../pages/[building]/homePage";
    
    describe("Homepage tests", () => {
      beforeEach(() => {
        render(
          <TestWraper>
            <HomePage />
          </TestWraper>,
        );
      });
      it("Render logout button", () => {
        expect(
          screen.getByRole("heading", {
            name: /logout/i,
          }),
        ).toBeInTheDocument();
      });
    });
    

    And I get this error.

     console.error
          Error: Uncaught [TypeError: Cannot destructure property 'locale' of '(0 , B.useRouter)(...)' as it is null.]
              at reportException.
    

    It might be handy if there's some sort of example on how to write a basic test with it.

    opened by Nsttt 5
  • Usage with SSR (getServerSideProps) instead of SSG?

    Usage with SSR (getServerSideProps) instead of SSG?

    I can't use getStaticProps because I rely on getServerSideProps on some pages. How can I make my translations available? Is there an equivalent to getLocaleStaticProps() for SSR instead of SSG?

    opened by noahflk 3
  • pass t useI18n hook inside a another component

    pass t useI18n hook inside a another component

    I would like to know if there's an easy way to pass {t} as a props inside another components hooks don't work inside loops so I need a way to find the type of t in order to pass it as prop in my other component here an example:

    const { scopedT } = useI18n();
    const t = scopedT('table')
    buildTableHeader(t);
    
    export const buildHeadIncidents = (t: //What type should I put here): HeadCellItem[] => {
        // const { t } = useI18n(); // I can't call the hook here
        return [
            {
                name: 'title1',
                label: t('mykey'),
            },
            {
                name: 'title2',
                label: t('mykey'),
            },
            {
                name: 'title3',
                label: t('mykey'),
            }
        ];
    };
    

    Here is definition of t and scopedT used by next-international

        useI18n: () => {
            t: {
                <Key extends Extract<keyof Locale, string>, Value extends international_types.LocaleValue = Locale[Key]>(key: Key, ...params: international_types.Params<Value>["length"] extends 0 ? [] : [international_types.ParamsObject<Value>]): string;
                <Key_1 extends Extract<keyof Locale, string>, Value_1 extends international_types.LocaleValue = Locale[Key_1]>(key: Key_1, ...params: international_types.Params<Value_1>["length"] extends 0 ? [] : [ReactParamsObject<Value_1>]): React$1.ReactNode;
            };
            scopedT: <Scope extends international_types.Scopes<Locale>>(scope: Scope) => {
                <Key_2 extends international_types.LocaleKeys<Locale, Scope, Extract<keyof Locale, string>>, Value_2 extends international_types.LocaleValue = international_types.ScopedValue<Locale, Scope, Key_2>>(key: Key_2, ...params: international_types.Params<Value_2>["length"] extends 0 ? [] : [international_types.ParamsObject<Value_2>]): string;
                <Key_3 extends international_types.LocaleKeys<Locale, Scope, Extract<keyof Locale, string>>, Value_3 extends international_types.LocaleValue = international_types.ScopedValue<Locale, Scope, Key_3>>(key: Key_3, ...params: international_types.Params<Value_3>["length"] extends 0 ? [] : [ReactParamsObject<Value_3>]): React$1.ReactNode;
            };
        };
    
    opened by chaosLegacy 2
  • Object spreading locales breaks variable inference

    Object spreading locales breaks variable inference

    In an effort to make my locale structure cleaner I have begun splitting it into multiple files / objects that I can import & object spread in the locale index default export.

    However there currently seems to be a bug whereby object spreading breaks the variable type inference.

    I've created a CodeSandbox to demonstrate the issue

    I feel like this may be more of a lower level TypeScript template inference issue but thought I would report it anyway 🙂

    opened by NuroDev 2
  • feat(next-international): use a regex to allow multiple interpolations

    feat(next-international): use a regex to allow multiple interpolations

    Right now it`s not possible to use a translation text that uses the same variable more than once, because only the first instance will be interpolated

    opened by cstrnt 2
  • feat: allow SSR and SSG with getLocaleProps

    feat: allow SSR and SSG with getLocaleProps

    Closes #23

    This PR renames getLocaleStaticProps to getLocaleProps and makes it possible to use with both getStaticProps or getServerSideProps.

    To not introduce a breaking change, the existing getLocaleStaticProps still exists and forward to getLocaleProps

    enhancement 
    opened by QuiiBz 0
  • fix: correct syntax for peer deps

    fix: correct syntax for peer deps

    Without this I wasn't able to install the library in an npm project. pnpm seems to be fine with the syntax either way.

    The error I had before this fix

    npm ERR! Found: [email protected]
    npm ERR! node_modules/next
    npm ERR!   next@"12.2.4" from the root project
    npm ERR!
    npm ERR! Could not resolve dependency:
    npm ERR! peer next@"12.x | 11.x" from [email protected]
    npm ERR! node_modules/next-international
    npm ERR!   next-international@"*" from the root project
    npm ERR!
    npm ERR! Fix the upstream dependency conflict, or retry
    npm ERR! this command with --force, or --legacy-peer-deps
    npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
    
    opened by noahflk 0
  • Package incompatible with Next.JS 13 `/app` directory

    Package incompatible with Next.JS 13 `/app` directory

    Since Next.JS's new /app directory moves away from built-in i18n support and instead advises to use generateStaticParams and middleware in the app directory, are you planning on adding such a middleware solution to this package? Currently the usage of useRouter crashes the I18nProvder in the new version of Next.JS

    opened by saphewilliam 2
  •  i18n support is not compatible with next export

    i18n support is not compatible with next export

    When running next export I get the following error

    Error: i18n support is not compatible with next export. See here for more info on deploying: https://nextjs.org/docs/deployment

    I found this tutorial: https://dev.to/adrai/static-html-export-with-i18n-compatibility-in-nextjs-8cd the solution was provided from next-i18next, wan we use the same approach for next-international?

    Since I couldn't fine anything in the README nor inside the closed issues , do you recommend following this solution or is there an alternative way for next-international?

    opened by chaosLegacy 3
  • [RFC]: CLI Tool that transforms the language TS files to JSON and vice versa

    [RFC]: CLI Tool that transforms the language TS files to JSON and vice versa

    Problem

    At my work we need to have the language files in JSON because they are inserted in some tool by the translation team. Manually converting this is quite a pain and repetitive work.

    Idea

    I think it would be cool to have a dedicated CLI tool that can convert JSON to TS and vice versa. Maybe it could also add wrap them in defineLocale to ensure typesafety along the files

    opened by cstrnt 1
  • [RFC] Add `useScopedT` hook

    [RFC] Add `useScopedT` hook

    I often end up having this exact code in my component

    function MyComponent() {
      const { scopedT } = usei18n();
      const t = scopedT("myScope");
    }
    

    I personally think that this is unnecessary overhead. I would prefer to have an export like useScopedT that takes in a scope and returns a t function with a defined scope

    opened by cstrnt 3
  • Nested object scopes

    Nested object scopes

    Hi! I really like this project, definitely my favorite nextjs i18n library that I've seen. Keep it up!

    One thing I didn't like about the locale definition was that scopes are defined with dot-separated strings, so I wrote a code snippet that allows me to define a locale in terms of a nested object like so:

    export interface OldLocale {
      'pages.landing.title': string;
      'pages.landing.description': string;
    }
    
    export interface Locale {
        pages: {
            landing: {
                title: string;
                description: string;
            };
        };
    }
    

    The code snippet is:

    import { createI18n } from "next-international";
    import type { Locale } from "@locales";
    
    const i18n = createI18n<Record<LocaleKeys<Locale>, string>>({
        en: () => import("@locales/en"),
        nl: () => import("@locales/nl"),
    });
    
    export const { useI18n, useChangeLocale, I18nProvider, getLocaleStaticProps } = i18n;
    
    type LocaleDefinition = Record<string, string | object>;
    type LocaleKeys<T> = keyof {
        [P in keyof T as T[P] extends string ? P : `${string & P}.${string & LocaleKeys<T[P]>}`]: true;
    };
    type DefinedLocale = Record<LocaleKeys<Locale>, string>;
    
    export function defineLocale(locale: Locale): DefinedLocale {
        const flatten = (l: Locale, prefix = ""): LocaleDefinition =>
            Object.entries(l).reduce(
                (prev, [name, value]) => ({
                    ...prev,
                    ...(typeof value === "string"
                        ? { [prefix + name]: value }
                        : flatten(value as Locale, `${prefix}${name}.`)),
                }),
                {},
            );
        return flatten(locale) as DefinedLocale;
    }
    

    Then I can define a locale like this

    import { defineLocale } from "@hooks/useI18n";
    
    export default defineLocale({
        landing: {
            hero: {
                title: "Welcome to my website",
                description: "This is a really cool website!",
            },
        },
    });
    

    Type-checking works within a locale definition, and the type system after createI18n seems to be unbothered.

    Just thought I'd share my solution, maybe you like it enough to implement it in the library. If not, feel free to close this issue 😃

    opened by saphewilliam 2
  • Lot of potential but too strongly bounded by nextjs.

    Lot of potential but too strongly bounded by nextjs.

    I want to use it in a react native project but just because it's using GetStaticProps and Router from next hence it can't be used anywhere except the next js project.

    I see a lot of potential in this library if it was not strongly bounded to one library. This can easily work in any react based project.

    U can provide optional "no configuration" and "automatic binding" for the next js as an extension for this library.

    Thoughts?

    opened by akashraj9828 6
Releases(0.3.6)
  • 0.3.6(Oct 17, 2022)

    What's Changed

    • feat(international-types): allow more values for locales by @QuiiBz in https://github.com/QuiiBz/next-international/pull/31
    • feat(international-types): support plural forms by @QuiiBz in https://github.com/QuiiBz/next-international/pull/32
    • feat(international-types): improve plural params by @QuiiBz in https://github.com/QuiiBz/next-international/pull/33
    • fix(international-types): multiple params in plural by @QuiiBz in https://github.com/QuiiBz/next-international/pull/34
    • chore(docs): add basic test example in readme by @Nsttt in https://github.com/QuiiBz/next-international/pull/37
    • fix(next-international): don't load locale client-side if SSR/SSGed by @QuiiBz in https://github.com/QuiiBz/next-international/pull/39

    New Contributors

    • @Nsttt made their first contribution in https://github.com/QuiiBz/next-international/pull/37

    Full Changelog: https://github.com/QuiiBz/next-international/compare/0.3.0...0.3.6

    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Aug 20, 2022)

    What's Changed

    • chore(docs): fix typo in examples by @ivanhofer in https://github.com/QuiiBz/next-international/pull/26
    • feat(next-international): use a regex to allow multiple interpolations by @cstrnt in https://github.com/QuiiBz/next-international/pull/30
    • feat: implement react translation functions by @EXio4 in https://github.com/QuiiBz/next-international/pull/29

    New Contributors

    • @ivanhofer made their first contribution in https://github.com/QuiiBz/next-international/pull/26
    • @cstrnt made their first contribution in https://github.com/QuiiBz/next-international/pull/30
    • @EXio4 made their first contribution in https://github.com/QuiiBz/next-international/pull/29

    Full Changelog: https://github.com/QuiiBz/next-international/compare/0.2.0...0.3.0

    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Aug 17, 2022)

    What's Changed

    • chore(docs): fix logo src by @QuiiBz in https://github.com/QuiiBz/next-international/pull/21
    • test(international-types): add type tests by @QuiiBz in https://github.com/QuiiBz/next-international/pull/22
    • fix: correct syntax for peer deps by @noahflk in https://github.com/QuiiBz/next-international/pull/24
    • feat: allow SSR and SSG with getLocaleProps by @QuiiBz in https://github.com/QuiiBz/next-international/pull/25

    New Contributors

    • @noahflk made their first contribution in https://github.com/QuiiBz/next-international/pull/24

    Full Changelog: https://github.com/QuiiBz/next-international/compare/0.1.1...0.2.0

    Source code(tar.gz)
    Source code(zip)
  • 0.1.1(Aug 2, 2022)

    What's Changed

    • test: add I18nProvider tests by @QuiiBz in https://github.com/QuiiBz/next-international/pull/16
    • test: useI18n 100% coverage by @QuiiBz in https://github.com/QuiiBz/next-international/pull/17
    • chore: update peer deps version by @QuiiBz in https://github.com/QuiiBz/next-international/pull/18
    • feat: introduce international-types by @QuiiBz in https://github.com/QuiiBz/next-international/pull/20

    Full Changelog: https://github.com/QuiiBz/next-international/compare/0.1.0...0.1.1

    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Jul 27, 2022)

    What's Changed

    • feat: minify some code by @QuiiBz in https://github.com/QuiiBz/next-international/pull/13
    • feat: add fallback locale by @QuiiBz in https://github.com/QuiiBz/next-international/pull/14

    New Contributors

    • @QuiiBz made their first contribution in https://github.com/QuiiBz/next-international/pull/1

    Full Changelog: https://github.com/QuiiBz/next-international/commits/0.1.0

    Source code(tar.gz)
    Source code(zip)
Owner
Tom Lienard
@scaleway intern, @withfig developer
Tom Lienard
The alternative internationalization (i18n) library for Angular

NGX Locutus The alternative Angular Translation Library used for large scale microfrontend translations. No more worrying about shared translation ass

Stefan Haas 9 May 31, 2022
human friendly i18n for javascript (node.js + browser)

BabelFish - human friendly i18n for JS Internationalisation with easy syntax for node.js and browser. Classic solutions use multiple phrases for plura

Nodeca 246 Nov 20, 2022
lightweight jQuery plugin for providing internationalization to javascript from ‘.properties’ files

jQuery.i18n.properties About jQuery.i18n.properties is a lightweight jQuery plugin for providing internationalization to javascript from ‘.properties’

null 408 Dec 25, 2022
🌐jQuery based internationalization library

jQuery.i18n NOTE: For jquery independent version of this library, see https://github.com/wikimedia/banana-i18n jQuery.i18n is a jQuery based Javascrip

Wikimedia 649 Jan 4, 2023
:globe_with_meridians: Internationalization plugin for Vue.js

vue-i18n Internationalization plugin for Vue.js ?? Gold Sponsors ?? Silver Sponsors ?? Bronze Sponsors ⚠️ NOTICE This repository is for Vue I18n v8.x.

kazuya kawaguchi 6.9k Dec 29, 2022
A JavaScript Internationalization Framework

FBT is an internationalization framework for JavaScript designed to be not just powerful and flexible, but also simple and intuitive. It helps with th

Facebook 3.8k Jan 8, 2023
🌍📖 A readable, automated, and optimized (5 kb) internationalization for JavaScript

Linguijs ?? ?? A readable, automated, and optimized (5 kb) internationalization for JavaScript Documentation · Documentation 2.x · Quickstart · Exampl

Lingui 3.5k Jan 2, 2023
ICU MessageFormat for Javascript - i18n Plural and Gender Capable Messages

messageformat The experience and subtlety of your program's text can be important. Messageformat is a mechanism for handling both pluralization and ge

null 1.6k Dec 23, 2022
A general purpose internationalization library in 292 bytes

A general purpose internationalization library in 298 bytes! Features Simple and Familiar API Unobstrusive and Unopinionated Less than 300 bytes – inc

Luke Edwards 713 Dec 21, 2022
ICU MessageFormat for Javascript - i18n Plural and Gender Capable Messages

messageformat The experience and subtlety of your program's text can be important. Messageformat is a mechanism for handling both pluralization and ge

null 1.6k Dec 23, 2022
Gettext Style i18n for Modern JavaScript Apps

Jed Gettext Style i18n for Modern JavaScript Apps For more info

null 879 Dec 14, 2022
Extract and merge i18n xliff translation files for angular projects.

Angular extract i18n and merge This extends Angular CLI to improve the i18n extraction and merge workflow. New/removed translations are added/removed

Daniel Schreiber 86 Jan 5, 2023
Merges XLIFF 1.2/2.0 files. Usable for Angular i18n automation.

XLIFF Simple Merge This program automates the merging of XLIFF files (version 1.2 and 2.0). New translations from the input file (e.g. "messages.xlf")

Daniel Schreiber 9 Dec 15, 2022
A fully type-safe and lightweight internationalization library for all your TypeScript and JavaScript projects.

?? typesafe-i18n A fully type-safe and lightweight internationalization library for all your TypeScript and JavaScript projects. Advantages ?? lightwe

Hofer Ivan 1.3k Jan 4, 2023
Internationalization for react done right. Using the i18next i18n ecosystem.

react-i18next IMPORTANT: Master Branch is the new v10 using hooks. $ v10.0.0 npm i react-i18next react-native: To use hooks within react-native, you m

i18next 7.9k Jan 9, 2023
Internationalization for react done right. Using the i18next i18n ecosystem.

react-i18next IMPORTANT: Master Branch is the new v10 using hooks. $ v10.0.0 npm i react-i18next react-native: To use hooks within react-native, you m

i18next 7.9k Dec 30, 2022
The alternative internationalization (i18n) library for Angular

NGX Locutus The alternative Angular Translation Library used for large scale microfrontend translations. No more worrying about shared translation ass

Stefan Haas 9 May 31, 2022
i18n-language.js is Simple i18n language with Vanilla Javascript

i18n-language.js i18n-language.js is Simple i18n language with Vanilla Javascript Write by Hyun SHIN Demo Page: http://i18n-language.s3-website.ap-nor

Shin Hyun 21 Jul 12, 2022
Framework agnostic CLI tool for routes parsing and generation of a type-safe helper for safe route usage. 🗺️ Remix driver included. 🤟

About routes-gen is a framework agnostic CLI tool for routes parsing and generation of a type-safe helper for safe route usage. Think of it as Prisma,

Stratulat Alexandru 192 Jan 2, 2023
100% type-safe query builder for node-postgres :: Generated types, call any function, tree-shakable, implicit type casts, and more

⚠️ This library is currently in alpha. Contributors wanted! tusken Postgres client from a galaxy far, far away. your database is the source-of-truth f

alloc 54 Dec 29, 2022