useExtracted feedback
#2036
Replies: 57 comments 201 replies
-
|
Question from @jurerotar:
Answer: Yep, namespaces are being considered, they are currently only briefly mentioned in regard to monorepos in the catalog generation section. E.g.: const t = useExtracted('namespace');
t('Hey there!');… would generate e.g.: {
"namespace": {
"5VpL9Z": "Hey there"
}
}I think the point is valid and this should be clarified more visibly (and perhaps not just be a "future exploration"). The ultimate goal for Does that answer the question? |
Beta Was this translation helpful? Give feedback.
-
|
Quick poll: After reading the section on File formats & AI translation, which file format would you prefer as a default?
|
Beta Was this translation helpful? Give feedback.
-
|
Another poll: Do you prefer import {useExtracted} from 'next-intl';
function InlineMessages() {
const t = useExtracted();
return <h1>{t('Look ma, no keys!')}</h1>;
}import {useInlined} from 'next-intl';
function InlineMessages() {
const t = useInlined();
return <h1>{t('Look ma, no keys!')}</h1>;
}Please vote with your preference:
I'd also appreciate if you leave a comment here explaining why you prefer a particular option! (or why the alternative is bad) |
Beta Was this translation helpful? Give feedback.
-
|
Some thoughts on rich text formatting from @niieani:
I think it's an interesting approach, somewhere in the middle of using direct concatenation and using arguments in ICU strings. Kind of a hybrid solution in contrast to what the RFC currently discusses. |
Beta Was this translation helpful? Give feedback.
-
|
A first release is out in Learn more: |
Beta Was this translation helpful? Give feedback.
-
|
Thanks again for working on this. I wanted to share some initial feedback: 1. Source string in PO filesRight now, the In other frameworks using Gettext (like Phoenix), the It would be great to have an option for this behavior, or at least include the source string as a comment above each 2. Deterministic compilationCurrently, every Ideally, the output should be deterministic and only update when translations are actually added, modified, or removed. |
Beta Was this translation helpful? Give feedback.
-
|
Something else I just noticed: Fallback for untranslated stringsRight now, untranslated strings render as empty. It would be great if they could fall back to the default locale. For example, if a string isn’t yet translated to |
Beta Was this translation helpful? Give feedback.
-
|
Is the package tree-shakeable and does it bundle only the messages used by the current page — similar to how @inlang/paraglide-sveltekit works for SvelteKit? |
Beta Was this translation helpful? Give feedback.
-
|
Should it work with monorepo? Seems like message aren't picked up from packages at build or dev. |
Beta Was this translation helpful? Give feedback.
-
|
i dont have src folder and i want extract from root folder so when use srcPath: "./",instead of srcPath: ["./actions", "./app", "./components", "./lib", "./schemas"],messages not extracted
|
Beta Was this translation helpful? Give feedback.
-
|
Will this work if |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
|
We use next-intl on all our websites with a dashboard that allows our customers to directly modify translations if they wish. Our workflow is as follows: we load the translations from the JSON, then we retrieve what comes from the database. We merge everything and send it. const json = (await import(`../../messages/${locale}.json`)).default
const flattened = flatten(json) as Record<string, string>
const url = new URL(`${publicEnv.NEXT_PUBLIC_BASE_URL}/api/i18n`)
url.searchParams.set('locale', locale)
const data = await fetch(url.toString())
.then(res => res.json())
.catch(() => ({}))
const messages = {
...flattened,
...data,
}
return {
locale,
messages: {
...(unflatten(messages) as Record<string, unknown>),
},
}With the system as developed here, our version is no longer possible because the keys change. However, if the keys do not change, then we can use the feature. Is it possible that the keys are the text as encoded? Something like : const t = useExtracted('namespace')
return <span>{t('Hello Github')}</span>conversion : {
"namespace": {
"Hello Github": "Hello Github"
}
}which would allow us to change the value in database while keeping the key ? Edit: Looks like I'm not the only one wanting this feature :D #2036 (comment) |
Beta Was this translation helpful? Give feedback.
-
|
When merge default messages with untranslated messages still show empty String |
Beta Was this translation helpful? Give feedback.
-
|
getting this error in monorepo when using import { getExtracted } from "@repo/i18n/server";
export default async function Page() {
const t = await getExtracted();
return (
<h1>{t("title")}</h1>
);
}./apps/web/app/[locale]/page.tsx
Error evaluating Node.js code
ResolveMessage: Cannot find module 'next-intl/extractor/extractionLoader' from 'C:\Users\benna\dev\my-app\apps\web\.next\dev\build\chunks\[turbopack]_runtime.js' |
Beta Was this translation helpful? Give feedback.
-
|
While the feature by itself is orthogonal to It only requires adding a single |
Beta Was this translation helpful? Give feedback.
-
|
How we can use Extracted messages for react-email instead createTranslator API https://react.email/docs/guides/internationalization/next-intl#3-update-the-email-template |
Beta Was this translation helpful? Give feedback.
-
|
A question from @jokull:
I'd be curious too for those who have migrated. How did you do it? Was there something that was challenging? /cc @ceolinwill @kieranm |
Beta Was this translation helpful? Give feedback.
-
|
just to confirm: message extraction runs on |
Beta Was this translation helpful? Give feedback.
-
|
@amannn Quick question about the extraction lifecycle: I'm asking because I'm running into an issue with the I would have expected next build in CI to catch this and regenerate the file correctly, but it doesn't seem to. |
Beta Was this translation helpful? Give feedback.
-
|
should the turbopack loader be able to handle i.e. i have a ui package which has "exports": {
"./i18n/en": "./messages/en.po"
}and in // local .po file, works
const { default: messages } = await import("@/messages/en.po");
// import from monorepo package, does not work
const { default: fromPo } = await import("@repo/ui/i18n/en");see https://github.com/stefanprobst/issue-next-i18n error message: |
Beta Was this translation helpful? Give feedback.
-
|
Any chance the default POCodec could be added to the package exports, to make it available for importing into a custom codec for extension/customization? I'm thinking about removing the line numbers, but I'd prefer not to have to have a copy of POCodec.tsx sitting around in my repo. |
Beta Was this translation helpful? Give feedback.
-
|
@amannn Bug: Version: next-intl Repro: https://github.com/keyboy21/next-intl-bug-repro-app-router Error: Root cause: When // Source (valid .tsx)
const identity = <T,>(value: T): T => value;
// After extractionLoader (broken — <T> is parsed as JSX)
const identity = <T>(value: T): T => value;In Minimal repro ( import { getExtracted } from "next-intl/server";
const identity = <T,>(value: T): T => value; // ← extractionLoader breaks this
export default async function IndexPage() {
const t = await getExtracted();
return <div>{t("hello")} {identity("world")}</div>;
} |
Beta Was this translation helpful? Give feedback.
-
|
Hi, I'm thinking of adopting this workflow:
If we were to support say 30 languages, then small PRs that touch localization would be huge, this workflow would improve it from the developer's and reviewer's point of view. The reason I am sending this here, is that I want to check in if this is a workflow that aligns with This workflow would need the introduction of a way to prevent automatic extraction during I made a PR for this, feel free to merge, throw away, or change however you'd like: #2292 |
Beta Was this translation helpful? Give feedback.
-
|
did anyone facing Hydration failed at latest nextjs 16.2.1? if using 16.1.7 is fine. Uncaught Error: Hydration failed because the server rendered text didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:
- A server/client branch `if (typeof window !== 'undefined')`.
- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.
- Date formatting in a user's locale which doesn't match the server.
- External changing data without sending a snapshot of it along with the HTML.
- Invalid HTML tag nesting.
It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.
https://react.dev/link/hydration-mismatch
...
<div className="`gap-y-3 f...">
<CompanyLogo>
<FormProvider control={{...}} subscribe={function subscribe} trigger={function trigger} ...>
<form onSubmit={function} className="min-w-62.5...">
<FormField control={{...}} name="username" render={function render}>
<Controller control={{...}} name="username" render={function render}>
<FormItem>
<div data-slot="form-item" className="grid gap-2">
<FormLabel htmlFor="username">
<Label data-slot="form-label" data-error={false} className="data-[erro..." htmlFor="username">
<Label data-slot="form-label" className="flex items..." data-error={false} htmlFor="username">
<Primitive.label data-slot="form-label" className="flex items..." data-error={false} ...>
<label
data-slot="form-label"
className="flex items-center gap-2 text-sm leading-none font-medium select-none group-data..."
data-error={false}
htmlFor="username"
onMouseDown={function onMouseDown}
ref={null}
>
+ Username~
- Username
...
...some Unusual log happend: ⚠ Fast Refresh had to perform a full reload when ./apps/micron/locales/en.po.js changed. Read more: https://nextjs.org/docs/messages/fast-refresh-reload
⚠ Fast Refresh had to perform a full reload when ./apps/micron/locales/en.po.js changed. Read more: https://nextjs.org/docs/messages/fast-refresh-reload
GET /login 200 in 376ms (next.js: 29ms, proxy.ts: 81ms, application-code: 265ms)
GET /login 200 in 186ms (next.js: 97ms, proxy.ts: 15ms, application-code: 75ms)
GET /login 200 in 479ms (next.js: 86ms, proxy.ts: 23ms, application-code: 371ms)
GET /login 200 in 593ms (next.js: 66ms, proxy.ts: 60ms, application-code: 467ms)
GET /login 200 in 535ms (next.js: 122ms, proxy.ts: 19ms, application-code: 393ms)
GET /login 200 in 398ms (next.js: 27ms, proxy.ts: 29ms, application-code: 342ms) |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
|
One area that we could have better DX is monorepo support. It would be great if we could have something like this:
|
Beta Was this translation helpful? Give feedback.
-
|
I think there might be a bug related to Next's telemetry (detached-flush), and it's exposing some kind of non-deterministic saving of files. I've filed a bug with Next here around disabling this behavior if telemetry is disabled. No idea if it will ever get merged in. Regardless, with all the agentic workflows, we're seeing zombie processes popping up when 37651 1 08-09:17:38 /Users/andrew/.nvm/versions/node/v24.15.0/bin/node /Users/andrew/Developer/next-intl-demo/node_modules/.pnpm/next@16.2.4_babel-plugin-react-compiler@1.0.0_react-dom@19.2.5_react@19.2.5__react@19.2.5/node_modules/next/dist/telemetry/detached-flush.js dev /Users/andrew/Developer/next-intl-demo _events_6343.jsonThis is introducing behavior that is exposed when you switch branches with Git. The below will result in un-staged file:
This happens because those zombie processes are still watching files and running So, two major things here:
I wish I could provide an actual repository publicly that gets into this bad behavior, but the biggest offender is my company's project, so I can't give you access. I've attempted to reproduce this in a new fresh NextJS repo, but... of course I'm not able to. I don't want to throw agentic stuff at you, but I've been debugging this for weeks and finally narrowed it down to this detached-flush.js stuff, and this is what Claude gave me when I explained the scenario to it, so I have no idea if this is helpful.
We're testing with the following |
Beta Was this translation helpful? Give feedback.
-
|
🌐 next-intl 4.12 is out with
|
Beta Was this translation helpful? Give feedback.
-
|
🌐 next-intl 4.13 is out with a Auto-generated |
Beta Was this translation helpful? Give feedback.





Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Please use this thread to share feedback related to
useExtracted.This is my public TODO list for the feature: #2087 (but please keep the feedback here)
Beta Was this translation helpful? Give feedback.
All reactions