1.1.0 โ€ข Published 3 years ago

next-g11n v1.1.0

Weekly downloads
-
License
MIT
Repository
-
Last release
3 years ago

next-g11n ๐ŸŒ

Your toolbelt for translating Next.js apps

npm badge typescript badge

๐Ÿชก tailor-made for Next.js i18n Routing

๐Ÿ‘ฎ Type-safe dictionaries

โ˜๏ธ optimized for Server-Side Rendering

Getting started ๐Ÿ—

  1. Install the dependency yarn add next-g11n or npm i next-g11n

  2. Create your dictionary.ts (or any other name, actually)

typedefault
object-

The translation object/map. It can either carry one locale, or all. The object format is as follows:

{
  'locale-key': {
    'translation-key': 'value - number or string'
  }
}
// example dictionary.ts
const dictionary = {
  // top level are locales (de) or (de-at), for example
  en: {
    // these are the translation keys
    hello: 'Hi',
  },
  'de-de': {
    hello: 'Hallo',
  },
  'de-at': {
    hello: 'GrรผรŸ Gott',
  },
}
  1. Choose between Client-Side-only or Server-Side translations

Helper methods ๐Ÿง 

getLocale

Receives a router instance from Next.js useRouter and returns the current locale if supported by your app, or the defaultLocale.

const router = useRouter()
const g11nLocale = getLocale(router) as Locales

Client-side only ๐Ÿช

When you call your hook, establish the types for the dictionary

import type { NextPage } from 'next'
import { useG11n } from 'next-g11n'
import { DICTIONARY } from '../dictionary'

const Home: NextPage = () => {
  const { translate: t } = useG11n<typeof DICTIONARY>(DICTIONARY)

  return (
    <h1>{t('hello')}</h1>
  )
}

โš ๏ธ this strategy will bring in the entire Dictionary to your bundle

useFallback

When true, if the translation does not exist in dictionary, the key will show. When set to false, it will throw an error.

typedefault
booleanfalse

โ€  recomended for apps without TypeScript

Server-Side Rendering ๐ŸŒค

Static Translations

Translations which do not require interpolation, can be completely rendered on the Server-Side within getStaticProps. An object with all translated terms will be injected in your page props.

const Home = ({ hello }: InferGetStaticPropsType<typeof getStaticProps>) => {
  const router = useRouter()
  const g11nLocale = getLocale(router) as Locales

  return <h1 className={styles.title}>{hello[g11nLocale]}</h1>
}

export const getStaticProps = async () => {
  const hello = createStaticTerm<Keys, Locales>('hello', DICTIONARY)

  return {
    props: {
      hello,
    },
  }
}

Interpolated Terms

To interpolate terms there are 2 methods required. On the server-side itโ€™s required to map all possible translation terms (still with template variables) by locale with createFunctionTerm. That object can then be passed down to each page props. Once arriving on the client-side, itโ€™s required to use clientSideTranslate to map each translation term to its method to interpolate the term with each variable and assign the proper types.

Functions are not serializable out-of-the-box in JavaScript, and getStaticProps only passes down serialized object as its returned props. It is possible to call both methods on the server if you handle serializing the output functions. But then again, it will be required to deserializing them on the client-side.

createFunctionTerm (server-side)

This method will receive a translation key, and the whole dictionary. It will output a raw translation term (with uninterpolated variables). This is an object literal ready to be serialized by getStaticProps on its way to the client-side.

const rawTerm = createFunctionTerm('term', DICTIONARY)

clientSideTranslate (client-side)

Once on the client-side, this method will receive the raw term from createFunctionTerm and ouput one method for each supported locale. This method is a TypeScript generic, first parameter is your Locales exported from your whole dictionary, and the second is a string union with each available parameter for that translation term.

export type Locales = keyof typeof DICTIONARY

const Page = ({ rawTerm }: InferGetStaticPropsType<typeof getStaticProps>) => {
  const router = useRouter()
  const g11nLocale = getLocale(router) as Locales
  const term = clientSideTranslate<Locales, 'var1' | 'var2'>(rawTerm)

  return <h1>{term[g11nLocale]({ var1: 'foo', var2: 'bar' })}</h1>
}

Examples ๐Ÿฑ

directorydescription
client-sideminimal setup for Client-side translations
server-side-renderminimal setup for SSR-friendly translations

Additional info โ“

  • Support starts with Next.js i18n Routing, so v10+
  • Next.js is a peerDependency
  • React is a peerDependency

Glossary ๐Ÿ“–

abbreviationfull wordmeaning
i18ninternationalizationenable adaptation of a product to multiple languages
L10nlocalizationtranslating and customizing to a specific place
g11nglobalizationaddressing requirements to launch globally
1.1.0

3 years ago

1.0.0

3 years ago

0.1.1

3 years ago

0.1.0

3 years ago