# Lazy Translations

Lazy translation allows you to defer translation of a message until it's rendered, giving you flexibility in how and where you define messages in your code. With lazy translation, you can tag a string with the [`msg`](https://lingui.dev/ref/macro.md#definemessage) macro to create a *message descriptor* that can be saved, passed around as a variable, and rendered later.

## Usage Example[​](#usage-example "Direct link to Usage Example")

To render the message descriptor as a string-only translation, pass it to the [`i18n.t()`](https://lingui.dev/ref/core.md#i18n.t) method:

```
import { msg } from "@lingui/core/macro";

import { i18n } from "@lingui/core";



const favoriteColors = [msg`Red`, msg`Orange`, msg`Yellow`, msg`Green`];



export function getTranslatedColorNames() {

  return favoriteColors.map((color) => i18n.t(color));

}
```

## Usage in React[​](#usage-in-react "Direct link to Usage in React")

To render the message descriptor in a React component, pass its `id` to the [`Trans`](https://lingui.dev/ref/react.md#trans) component as a value of the `id` prop:

```
import { msg } from "@lingui/core/macro";

import { Trans } from "@lingui/react";



const favoriteColors = [msg`Red`, msg`Orange`, msg`Yellow`, msg`Green`];



export default function ColorList() {

  return (

    <ul>

      {favoriteColors.map((color) => (

        <li>

          <Trans id={color.id} />

        </li>

      ))}

    </ul>

  );

}
```

Important

Please note that we import the `<Trans>` component from `@lingui/react` to use the runtime version, as the message is already defined and we don't need the compile-time macro here.

### Picking a Message Based on a Variable[​](#picking-a-message-based-on-a-variable "Direct link to Picking a Message Based on a Variable")

Sometimes you need to choose between different messages to display depending on the value of a variable. For example, imagine you have a numeric "status" code that comes from an API, and you need to display a message that represents the current status.

An easy way to do this is to create an object that maps the possible values of "status" to message descriptors (tagged with the [`msg`](https://lingui.dev/ref/macro.md#definemessage) macro) and render them as needed with deferred translation:

```
import { msg } from "@lingui/core/macro";

import { useLingui } from "@lingui/react";



const statusMessages = {

  ["STATUS_OPEN"]: msg`Open`,

  ["STATUS_CLOSED"]: msg`Closed`,

  ["STATUS_CANCELLED"]: msg`Cancelled`,

  ["STATUS_COMPLETED"]: msg`Completed`,

};



export default function StatusDisplay({ statusCode }) {

  const { _ } = useLingui();

  return <div>{_(statusMessages[statusCode])}</div>;

}
```

### Memoization Pitfall[​](#memoization-pitfall "Direct link to Memoization Pitfall")

In the following contrived example, we document how a welcome message will or will not be updated when locale changes. The documented behavior may not be intuitive at first, but it is expected, because of the way the `useMemo` dependencies work.

To avoid bugs with stale translations, use the `t` function returned from the [`useLingui`](https://lingui.dev/ref/macro.md#uselingui) macro: it is safe to use with memoization because its reference changes whenever the Lingui context updates.

Keep in mind that `useMemo` is primarily a performance optimization tool in React. Because of this, there might be no need to memoize your translations. Additionally, this issue is not present when using the `Trans` component, which we recommend using whenever possible.

```
import { i18n } from "@lingui/core";

import { msg } from "@lingui/core/macro";

import { useLingui } from "@lingui/react/macro";



const welcomeMessage = msg`Welcome!`;



// ❌ Bad! This code won't work

export function Welcome() {

  const buggyWelcome = useMemo(() => {

    return i18n.t(welcomeMessage);

  }, []);



  return <div>{buggyWelcome}</div>;

}



// ❌ Bad! This code won't work either because the reference to i18n does not change

export function Welcome() {

  const { i18n } = useLingui();



  const buggyWelcome = useMemo(() => {

    return i18n.t(welcomeMessage);

  }, [i18n]);



  return <div>{buggyWelcome}</div>;

}



// ✅ Good! `useMemo` consumes the `t` function from the `useLingui` macro

export function Welcome() {

  const { t } = useLingui();



  const welcome = useMemo(() => {

    return t(welcomeMessage);

  }, [t]);



  return <div>{welcome}</div>;

}
```
