Published on
3 min read

gt-next@6.5.0

Authors

Overview

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


Motivation

"Brown field" and "green field" are terms borrowed from real estate development. A green field is a lot without existing structures, while a brown field has existing structures. In i18n, this translates to apps without i18n infrastructure (green field) versus apps that already have i18n infrastructure (brown field).

Our library has been incredibly focused on internationalizing "green field" apps up until this point. Consider the <T> component or the useGT() hook as examples.

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

What we've discovered 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 would need 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 green field and brown field applications. By enabling developers to work with dictionary subtrees directly, we're removing a major friction point in internationalizing 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 internationalized applications.