Back

gt-next@6.6.0

Ernest McCarter avatarErnest McCarter
gt-next6.6.0Dictionary translationtranslation

Overview

In gt-next 6.6.0, we're taking a new approach to internationalising "brown field" apps. We're introducing the t.obj() function, which can return translated dictionary structures.


Motivation

"Brownfield" and "greenfield" are terms borrowed from real estate development. A greenfield is a plot without existing structures, while a brownfield has existing structures. In i18n, this translates to apps without i18n infrastructure (greenfield) versus apps that already have i18n infrastructure (brownfield).

Our library has been heavily focused on internationalising "greenfield" apps up until this point. Consider the <T> component or the useGT() hook as examples.

The only infrastructure we've built specifically for "brownfield" apps is the const t = useTranslations() and const t = getTranslations() hooks, modelled after next-intl's dictionary pattern. However, our t() function has been limited, only returning strings, not dictionary subtrees.

What we've found is that developers often expect their i18n library to return dictionary subtrees, not just strings. This makes it essential for gt-next to support this feature when developers are transitioning from other i18n libraries.


Usage

Consider the following dictionary structure, where you have a list of items you want to iterate over:

{
  "cards": [
    {
      "title": "Card 1",
      "description": "Card 1 description"
    },
    {
      "title": "Card 2",
      "description": "Card 2 description"
    },
    {
      "title": "Card 3",
      "description": "Card 3 description"
    }
  ]
}

With our previous approach, you’d have to access each item individually using its exact key:

import { useTranslations } from 'gt-next'

export default function Page() {
  const t = useTranslations()

  return (
    <>
      <div>
        {t('cards.0.title')}
        {t('cards.0.description')}
      </div>
      <div>
        {t('cards.1.title')}
        {t('cards.1.description')}
      </div>
      <div>
        {t('cards.2.title')}
        {t('cards.2.description')}
      </div>
    </>
  )
}

This approach is clearly not scalable or maintainable.

The new t.obj() function provides a powerful way to access dictionary structures as subtrees:

import { useTranslations } from 'gt-next'

export default function Page() {
  const t = useTranslations()

  return (
    <>
      <div>
        {t.obj('cards').map((card) => (
          <div key={card.title}>
            {card.title}
            {card.description}
          </div>
        ))}
      </div>
    </>
  )
}

Conclusion

The t.obj() function represents a significant step forward in making gt-next more versatile for both greenfield and brownfield applications. By enabling developers to work with dictionary subtrees directly, we're removing a major friction point in internationalising existing applications.

This enhancement brings gt-next closer to the developer experience that teams expect from modern i18n libraries, making it easier to iterate over translated content and build more dynamic, maintainable internationalised applications.