-
-
Notifications
You must be signed in to change notification settings - Fork 106
Description
Today I started experimenting with Intlayer on NextJS 16, after following the setup from Intlayer docs, I noticed some errors on my NextJS application when using the html function to render some components. Here are two examples that cause issues:
The first one is using the use method on description and passing it a component for rendering, when you inspect the output on the browser, you will notice a nested tag of the same element (duplicate). This could produce invalid html when using "p" elements, NextJS Link component or a combination that could produce let's say a div inside a p element.
NOTE: FieldDescription component is what renders the p element.
// demo.content.ts
description: t({
en: html("Already have an account? <SignIn>Sign in<SignIn/>"),
es: html("¿Ya tienes una cuenta? <SignIn>Inicia sesión</SignIn>")
})
// component.ts
<FieldDescription>
{t.description.use({
SignIn: ({ children }) => {
return <a>{children}</a>
},
})}
</FieldDescription>
// renders
<p>
Already have an account?{" "}
<a>
Sign in
<a></a>
</a>
</p>
The same happens even without using "use" method.
// demo.content.ts
description: t({
en: html("Already have an account? <a>Sign in<a/>"),
es: html("¿Ya tienes una cuenta? <a>Inicia sesión</a>"),
}),
// component.ts
<FieldDescription>
{t.description}
</FieldDescription>
// renders
<p>
Already have an account?{" "}
<a>
Sign in
<a></a>
</a>
</p>
Here are some NextJS logs from the first example:
## Error Type
Console Error
## Error Message
In HTML, <a> cannot be a descendant of <a>.
This will cause a hydration error.
...
<m fallback={[...]}>
<f>
<p locale="en">
<SignUpForm>
<div className="flex w-ful...">
<form onSubmit={function onSubmit}>
<FieldGroup>
<div data-slot="field-group" className="group/fiel...">
<div className="flex flex-...">
<h1>
<FieldDescription>
<p data-slot="field-desc..." className={"text-lef..."}>
<s dictionaryKey="sign-up-form" dictionaryPath={undefined} keyPath={[...]} html={"Already ..."} ...>
<f dictionaryKey="sign-up-form" dictionaryPath={undefined} keyPath={[...]} html={"Already ..."} ...>
> <a>
> <a>
...
at a (<anonymous>:null:null)
at SignUpForm (src/packages/auth-react/users/sign-up/components/form.tsx:95:30)
at Page (src/app/[locale]/(auth)/sign-up/page.tsx:12:9)
## Code Frame
93 |
94 | <FieldDescription>
> 95 | {t.description.use({
| ^
96 | SignIn: ({ children }) => {
97 | return <a>{children}</a>
98 | },
Next.js version: 16.1.6 (Turbopack)
## Error Type
Recoverable Error
## Error Message
Hydration failed because the server rendered HTML 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
at a (<anonymous>:null:null)
at SignUpForm (src/packages/auth-react/users/sign-up/components/form.tsx:95:30)
at Page (src/app/[locale]/(auth)/sign-up/page.tsx:12:9)
## Code Frame
93 |
94 | <FieldDescription>
> 95 | {t.description.use({
| ^
96 | SignIn: ({ children }) => {
97 | return <a>{children}</a>
98 | },
Next.js version: 16.1.6 (Turbopack)
This is my first day using Intlayer so I'm not sure if I am missing something, and I couldn't find anything related to this on the repo issues, intlayer docs or online. Does someone else have the same issue?