Skip to content

Commit 9f68d89

Browse files
committed
fix: hardcoded locale in IntlFormatMessage
1 parent 6db156c commit 9f68d89

File tree

5 files changed

+61
-30
lines changed

5 files changed

+61
-30
lines changed

cmp/compiler/src/react/client/useTranslation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export const useTranslation: TranslationHook = (hashes: string[]) => {
6565
return text;
6666
}
6767

68-
return renderRichText(text, params);
68+
return renderRichText(text, params, locale);
6969
},
7070
[translations, locale, sourceLocale],
7171
),

cmp/compiler/src/react/server-only/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export async function getServerTranslations(options: {
7474
return text;
7575
}
7676

77-
return renderRichText(text, params);
77+
return renderRichText(text, params, locale);
7878
},
7979
locale,
8080
translations,

cmp/compiler/src/react/server/useTranslation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export const useTranslation: TranslationHook = (hashes: string[]) => {
7373
return text;
7474
}
7575

76-
return renderRichText(text, params);
76+
return renderRichText(text, params, locale);
7777
},
7878
locale,
7979
};

cmp/compiler/src/react/shared/render-rich-text.test.tsx

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import {
66
describe,
77
expect,
88
it,
9-
type SerializedConfig,
109
type SnapshotSerializer,
1110
} from "vitest";
1211
import React, { isValidElement, type ReactElement } from "react";
1312
import { renderRichText } from "./render-rich-text";
1413

1514
const SERIALIZED_MARKER = Symbol("serialized");
15+
const LOCALE = "en";
1616

1717
const serializer = {
1818
serialize(val: ReactElement, config, indentation, depth, refs, printer) {
@@ -47,27 +47,35 @@ describe("renderRichText", () => {
4747
});
4848

4949
it("should return plain text when only text (no placeholders)", () => {
50-
const result = renderRichText("Hello World", {});
50+
const result = renderRichText("Hello World", {}, LOCALE);
5151
expect(result).toBe("Hello World");
5252
});
5353

5454
it("should replace variable placeholders", () => {
55-
const result = renderRichText("Hello {name}", { name: "Alice" });
55+
const result = renderRichText("Hello {name}", { name: "Alice" }, LOCALE);
5656
expect(result).toBe("Hello Alice");
5757
});
5858

5959
it("should replace multiple variable placeholders", () => {
60-
const result = renderRichText("Hello {name}, you have {count} messages", {
61-
name: "Bob",
62-
count: 5,
63-
});
60+
const result = renderRichText(
61+
"Hello {name}, you have {count} messages",
62+
{
63+
name: "Bob",
64+
count: 5,
65+
},
66+
LOCALE,
67+
);
6468
expect(result).toBe("Hello Bob, you have 5 messages");
6569
});
6670

6771
it("should render component placeholders with JSX", () => {
68-
const result = renderRichText("Click <a0>here</a0>", {
69-
a0: (chunks) => <a href="/home">{chunks}</a>,
70-
});
72+
const result = renderRichText(
73+
"Click <a0>here</a0>",
74+
{
75+
a0: (chunks) => <a href="/home">{chunks}</a>,
76+
},
77+
LOCALE,
78+
);
7179

7280
expect(result).toMatchSnapshot();
7381
});
@@ -80,16 +88,21 @@ describe("renderRichText", () => {
8088
count: 5,
8189
strong0: (chunks) => <strong>{chunks}</strong>,
8290
},
91+
LOCALE,
8392
);
8493

8594
expect(result).toMatchSnapshot();
8695
});
8796

8897
it("should render multiple same-type components", () => {
89-
const result = renderRichText("Click <a0>here</a0> or <a1>there</a1>", {
90-
a0: (chunks) => <a href="/home">{chunks}</a>,
91-
a1: (chunks) => <a href="/about">{chunks}</a>,
92-
});
98+
const result = renderRichText(
99+
"Click <a0>here</a0> or <a1>there</a1>",
100+
{
101+
a0: (chunks) => <a href="/home">{chunks}</a>,
102+
a1: (chunks) => <a href="/about">{chunks}</a>,
103+
},
104+
LOCALE,
105+
);
93106

94107
expect(result).toMatchSnapshot();
95108
});
@@ -109,16 +122,21 @@ describe("renderRichText", () => {
109122
</a>
110123
),
111124
},
125+
LOCALE,
112126
);
113127

114128
expect(result).toMatchSnapshot();
115129
});
116130

117131
it("should handle nested components inside component tags", () => {
118-
const result = renderRichText("You have <strong0>{count}</strong0> items", {
119-
count: 10,
120-
strong0: (chunks) => <strong>{chunks}</strong>,
121-
});
132+
const result = renderRichText(
133+
"You have <strong0>{count}</strong0> items",
134+
{
135+
count: 10,
136+
strong0: (chunks) => <strong>{chunks}</strong>,
137+
},
138+
LOCALE,
139+
);
122140

123141
expect(result).toMatchSnapshot();
124142
});
@@ -130,25 +148,34 @@ describe("renderRichText", () => {
130148
a0: (chunks) => <a>{chunks}</a>,
131149
a1: (chunks) => <a>{chunks}</a>,
132150
},
151+
LOCALE,
133152
);
134153

135154
expect(result).toMatchSnapshot();
136155
});
137156

138157
it("should render untranslatable content as is", () => {
139-
const result = renderRichText("Install using <code0></code0> command", {
140-
code0: () => <code>npm install package</code>,
141-
});
158+
const result = renderRichText(
159+
"Install using <code0></code0> command",
160+
{
161+
code0: () => <code>npm install package</code>,
162+
},
163+
LOCALE,
164+
);
142165
expect(result).toMatchSnapshot();
143166
});
144167

145168
it("should render fragments with expressions", () => {
146169
const translatableMixedContextFragment = (
147170
<>
148-
{renderRichText("<b0>Mixed</b0> content <i0>fragment</i0>", {
149-
b0: (chunks) => <b>{chunks}</b>,
150-
i0: (chunks) => <i>{chunks}</i>,
151-
})}
171+
{renderRichText(
172+
"<b0>Mixed</b0> content <i0>fragment</i0>",
173+
{
174+
b0: (chunks) => <b>{chunks}</b>,
175+
i0: (chunks) => <i>{chunks}</i>,
176+
},
177+
LOCALE,
178+
)}
152179
</>
153180
);
154181

@@ -157,6 +184,7 @@ describe("renderRichText", () => {
157184
{
158185
translatableMixedContextFragment,
159186
},
187+
LOCALE,
160188
);
161189
expect(result).toMatchSnapshot();
162190
});
@@ -165,6 +193,7 @@ describe("renderRichText", () => {
165193
const result = renderRichText(
166194
"To wrap text use: '<'>content'<'/> or '<'Fragment>content'<'/Fragment>",
167195
{},
196+
LOCALE,
168197
);
169198
expect(result).toBe(
170199
"To wrap text use: <>content</> or <Fragment>content</Fragment>",

cmp/compiler/src/react/shared/render-rich-text.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Fragment, type ReactNode } from "react";
22
import IntlMessageFormat, { type FormatXMLElementFn } from "intl-messageformat";
33
import { logger } from "../../utils/logger";
4-
import { sourceLocale } from "@lingo.dev/compiler/virtual/config";
4+
import type { LocaleCode } from "lingo.dev/spec";
55

66
/**
77
* Component renderer function for rich text translation
@@ -53,14 +53,16 @@ function assignUniqueKeysToParams(params: RichTextParams): RichTextParams {
5353
*
5454
* @param text - The translation string with placeholders
5555
* @param params - Object with variable values and component renderers
56+
* @param locale
5657
* @returns React nodes or string
5758
*/
5859
export function renderRichText(
5960
text: string,
6061
params: RichTextParams,
62+
locale: LocaleCode,
6163
): ReactNode {
6264
try {
63-
const formatter = new IntlMessageFormat(text, sourceLocale);
65+
const formatter = new IntlMessageFormat(text, locale);
6466
const keyedParams = assignUniqueKeysToParams(params);
6567
const result = formatter.format<ReactNode>(keyedParams);
6668

0 commit comments

Comments
 (0)