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

After upgrade to V4 dynamic ids did not work #1669

Closed
2 tasks
Strnadj opened this issue May 21, 2023 · 7 comments
Closed
2 tasks

After upgrade to V4 dynamic ids did not work #1669

Strnadj opened this issue May 21, 2023 · 7 comments

Comments

@Strnadj
Copy link

Strnadj commented May 21, 2023

Describe the bug
We are receiving some configuration from server, so we've decided to have some name convention for translations, like:

// Define all types to be extracted and translated
void t({ id: "message.unauthorized", message: "Unauthorized" });
void t({ id: "message.authorized", message: "Authorized" });
void t({ id: "message.verified", message: "Verified" });

// Actual execution code
const type = "unauthorized"; // Cames from BE
return t({ id: `message.${type}` });

The issue is since those catalogs are using hash<id> instead of the original <id>, this will never work. So we have to:

import { generateMessageId } from "@lingui/message-utils/generateMessageId";
return i18n._(generateMessageId(`message.${type}`);

But this requires importing the whole crypto etc. In the previous version "it just works", now is there any more elegant way how to do that? Also a section in the doc will be nice, I assume that we are not the only one who are dealing with this.

Additional context
Add any other context about the problem here.

  • jsLingui version 4.1.x
  • Babel version npm list @babel/core
  • Macro support:
  • I'm using SWC with @lingui/swc-plugin
  • [x ] I'm using Babel with babel-macro-plugin
  • I'm not using macro
  • React + webpack5
@thekip
Copy link
Collaborator

thekip commented May 22, 2023

// Define all types to be extracted and translated
void msg({ id: "message.unauthorized", message: "Unauthorized" });
void msg({ id: "message.authorized", message: "Authorized" });
void msg({ id: "message.verified", message: "Verified" });

// Actual execution code
const type = "unauthorized"; // Cames from BE
return i18n._({ id: `message.${type}` });

That should work, without generateMessageId

@Strnadj
Copy link
Author

Strnadj commented May 22, 2023

@thekip Yes you are right this works, I am using a clean fresh CRA + linguijs installation for my experiments. The problem seems to be in tests.

https://lingui.dev/guides/testing

My web pack is configured properly to use @lingui/loader for .po files, but jest can only import the compiled files, which is hash: ...

@Strnadj
Copy link
Author

Strnadj commented May 22, 2023

I am closing this in favor of #1304 you can either import compiled messages.js or it just did not work, because @lingui/loader is for webpack.

@Strnadj Strnadj closed this as completed May 22, 2023
@thekip
Copy link
Collaborator

thekip commented May 22, 2023

It's much easier when you don't use explicit ids. It "just works" in tests as well. But in your case, before test you can mock catalog messages exactly for you test case and not rely on a real catalog. (that's even better, because test would be less depend on messages itself)

@nnarayen
Copy link

I think I have a similar issue! I have dynamic strings coming from my BE, but I know all the possible values ahead of time.

Currently, I have duplicated all the options on the FE as well:

export const MyStringValues = [
  msg`First`,
  msg`Second`,
  ...
]

And then my React component looks like:

// sVal here is always either First or Second
export const MyReactComponent = ({ sVal }: { sVal: string }) => {
  const { _ } = useLingui();

  return <div>{_(sVal)}</div>;
};

However, as the original poster suggested, this doesn't work because the runtime code expects the generated IDs. I would prefer to use the auto generated IDs, but I'm not quite sure how to do so. The examples I've seen all seem to iterate over message descriptors instead of dynamic data passed straight from BE.

I'm on lingui 4.10.1 and using the experimental swc plugin with NextJS. Thanks in advance!

@thekip
Copy link
Collaborator

thekip commented May 28, 2024

export const MyStringValues = {
  'First': msg`First`,
  'Second': msg`Second`,
  ...
}

than

// sVal here is always either First or Second
export const MyReactComponent = ({ sVal }: { sVal: string }) => {
  const { _ } = useLingui();

  return <div>{_(MyStringValues[sVal])}</div>;
};

@nnarayen
Copy link

nnarayen commented May 28, 2024

Awesome! We ended up with basically that exact approach, but weren't sure if we were doing anything unexpected with the extra keys. Thanks for the super quick response here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants