Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional translations #88

Open
amannn opened this issue Mar 9, 2022 · 7 comments
Open

Optional translations #88

amannn opened this issue Mar 9, 2022 · 7 comments
Labels
area: ergonomics enhancement New feature or request

Comments

@amannn
Copy link
Owner

amannn commented Mar 9, 2022

Is your feature request related to a problem? Please describe.

It would be good if some translations could be marked as optional, so no error is reported.

Describe the solution you'd like

Either an API to ask if a translation is available to conditionally render it, or an API to suppress the error in this case.

Probably t.has(…) would be the best option here as it can be used to check for translations before using either t, t.rich, t.raw etc.

Describe alternatives you've considered

Adding empty strings in the messages if the label is not relevant for a particular scenario (i.e. "message": "").

If you're using the VSCode integration for next-intl via i18n Ally, you can add empty messages for new keys via "i18n-ally.keepFulfilled": true.

I'm currently unsure if next-intl needs built-in support for this, or if it can be solved with tooling. I guess the question is: "Is this translation missing currently or is it not intended at all?".

This could also be solved via a combination of useMessages and lodash/get, e.g. in a custom hook.

@Crayon-ShinChan
Copy link

Can we have these two features:

  1. If the translation does not exist, fallback to see the defaultLocale json file and use the word there
  2. Fallback to a specific language not always defaultLocale, If the translation from zh-TW does not exist, fallback to show words in zh

@Crayon-ShinChan
Copy link

Can we have these two features:

  1. If the translation does not exist, fallback to see the defaultLocale json file and use the word there
  2. Fallback to a specific language not always defaultLocale, If the translation from zh-TW does not exist, fallback to show words in zh

I use this code to implement the logic:

import merge from "deepmerge";
import { getRequestConfig } from "next-intl/server";

export default getRequestConfig(async ({ locale }) => {
  const localeMessages = (await import(`./messages/${locale}.json`)).default;
  const localeGeneralMessages =
    locale.split("-").length > 1
      ? (await import(`./messages/${locale.split("-")[0]}.json`)).default
      : {};
  const defaultMessages = (await import(`./messages/en.json`)).default;
  const messages = merge.all([
    defaultMessages,
    localeGeneralMessages,
    localeMessages,
  ]);

  return {
    messages,
  };
});

It can run successfully, but give me the type warning for async ({ locale })

Argument of type '({ locale }: GetRequestConfigParams) => Promise<{ messages: object; }>' is not assignable to parameter of type '(params: GetRequestConfigParams) => RequestConfig | Promise<RequestConfig>'.
  Type 'Promise<{ messages: object; }>' is not assignable to type 'RequestConfig | Promise<RequestConfig>'.
    Type 'Promise<{ messages: object; }>' is not assignable to type 'Promise<RequestConfig>'.
      Type '{ messages: object; }' is not assignable to type 'RequestConfig'.
        Types of property 'messages' are incompatible.
          Type 'object' is not assignable to type 'AbstractIntlMessages'.
            Index signature for type 'string' is missing in type '{}'.ts(2345)

anyone know how to solve this?

@amannn
Copy link
Owner Author

amannn commented Nov 3, 2023

Merging messages from another locale as a fallback is absolutely fine and also mentioned in the messages docs ("How can I use messages from another locale as fallbacks?").

@alejandroTecDam
Copy link

Can we have these two features:

  1. If the translation does not exist, fallback to see the defaultLocale json file and use the word there
  2. Fallback to a specific language not always defaultLocale, If the translation from zh-TW does not exist, fallback to show words in zh

I use this code to implement the logic:

import merge from "deepmerge";
import { getRequestConfig } from "next-intl/server";

export default getRequestConfig(async ({ locale }) => {
  const localeMessages = (await import(`./messages/${locale}.json`)).default;
  const localeGeneralMessages =
    locale.split("-").length > 1
      ? (await import(`./messages/${locale.split("-")[0]}.json`)).default
      : {};
  const defaultMessages = (await import(`./messages/en.json`)).default;
  const messages = merge.all([
    defaultMessages,
    localeGeneralMessages,
    localeMessages,
  ]);

  return {
    messages,
  };
});

It can run successfully, but give me the type warning for async ({ locale })

Argument of type '({ locale }: GetRequestConfigParams) => Promise<{ messages: object; }>' is not assignable to parameter of type '(params: GetRequestConfigParams) => RequestConfig | Promise<RequestConfig>'.
  Type 'Promise<{ messages: object; }>' is not assignable to type 'RequestConfig | Promise<RequestConfig>'.
    Type 'Promise<{ messages: object; }>' is not assignable to type 'Promise<RequestConfig>'.
      Type '{ messages: object; }' is not assignable to type 'RequestConfig'.
        Types of property 'messages' are incompatible.
          Type 'object' is not assignable to type 'AbstractIntlMessages'.
            Index signature for type 'string' is missing in type '{}'.ts(2345)

anyone know how to solve this?

I've solved the issue like this, but I only have two elements, maybe you can do two steps

const messages = merge(defaultMessages, localeMessages);

@philipbjorge
Copy link

My usecase:

Our backend is returning a State (e.g. Washington, Oregon, etc.)
We will have translations for all of the common states.

However, it is possible that a new value comes down the line.
I would like to be able to show a translated key if its present, otherwise just fall back to displaying the value returned by the API.


As far as I can tell, this isn't supported by this library?

@amannn
Copy link
Owner Author

amannn commented Feb 14, 2024

@philipbjorge Have you considered using select for this use case?

"state": "{state, select, WA {Washington} OR {Oregon} other {{state}}"

@philipbjorge
Copy link

Mmm interesting solution... We have 900 selections, so I feel like that string might become unwieldy. I think we might go with something like this since the key name is well-defined.

  const getTranslationWithFallback = (key: string, fallback: string) => {
    const translated = tc(key, false);
    if (translated.startsWith("common.")) {
      return fallback;
    }
    return translated;
  };

{getTranslationWithFallback(`biomes.${biome}`, biome)}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: ergonomics enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants