skip to Main Content

I created a custom Lingui wrapper in a React project:

function translate(translateObject: ITrenslatable) {
  const { i18n, id, fallback, values, comment } = translateObject;

  let translatedText = i18n._({
    id,
    message: fallback,
    values,
    comment,
  });

  if (translatedText == id) {
    translatedText = i18n._({
      id: Math.random().toString(),
      message: fallback,
      values,
      comment,
    });
  }

  return translatedText;
}

In the future, this custom wrapper may how additional features, and I’m also planning on making a <Translate /> tag that uses the function above under the hood to achieve custom translating behavior.

Edit: currently I need this function because:

  1. I want to create a layer of abstraction between my
    application and translation.
  2. I need this wrapper function to be able to provide a default
    value, because otherwise if there were missing translations (e.g.
    translation only available in English, and not Hungarian, only the
    id would be displayed when switched to Hungarian).

The custom function works exactly as expected when used on already extracted text, but unfortunately, I cannot extract from this function.

It looks like this when used:

translate({
      i18n,
      fallback: "User at {id}",
      id: "user.title",
      values: { id: props.id },
})

How do I make Lingui find and extract my custom translate function?

Thank you for reading!

2

Answers


  1. I have not used Lingui myself and did no try out this solution, but according to the documentation, what you should probably do is:

    Create a custom extractor that parses your code and inserts /*i18n*/ annotations to the calls of your translate function, so the parameters passed to this function can then be picked up by the default extractor:

    import { extractor as defaultExtractor } from "@lingui/cli/api";
    
    export const extractor: ExtractorType = {
      match(filename: string) {
        return defaultExtractor.match(filename);
      },
      extract(filename: string, code: string, onMessageExtracted, ctx: ExtractorCtx) {
        const annotatedCode = code.replace(/btranslates*(/, "translate( /*i18n*/ "
        return defaultExtractor.extract(filename, annotatedCode, onMessageExtracted, ctx);
      },
    };
    

    …and add your extractor to the lingui.config.ts file:

    import { extractor } from './my-custom-extractor.ts'
    module.exports = {
      [...]
      extractors: [extractor]
    }
    

    Please be aware that this is prone to some errors, e.g. if somebody choses to define an alias for the translate function like this, the extraction will not work:

    import {translate as t} from "your-package";
    
    Login or Signup to reply.
  2. You can customize how the lingui cli extracts strings, as documented here https://lingui.dev/ref/conf#runtimeconfigmodule

    I understand that you want to have an abstraction layer, but looking at your example, I don’t think what you’re doing is a good idea, and I’d rather follow the approach recommended by the official docs.

    Also, if your if (translatedText == id) condition is meant to detect untranslated strings, it’s wrong – it will work only for simple use cases but not for plurals and other more complicated stuff.

    To provide fallbacks, look at https://lingui.dev/ref/conf#fallbacklocales

    Hope this helps! 🙂

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search