`Extra attributes from the server: data-fr-js-modal-button`
Hello
I've this warning using react-dsfr in my Remix project (here: https://github.com/betagouv/zacharie/tree/24f0594140d20aa8d93f271947c8dd62fdb83112)
I have no clue how to try and fix it...
Warning: Extra attributes from the server: data-fr-js-modal-button
at button
at http://localhost:3232/node_modules/.vite/deps/chunk-EIDWZ6ND.js?v=628cc138:41:15
at fr-theme-modal-modal
at Display (http://localhost:3232/node_modules/.vite/deps/@codegouvfr_react-dsfr_Header.js?v=628cc138:426:17)
at http://localhost:3232/node_modules/.vite/deps/@codegouvfr_react-dsfr_Header.js?v=628cc138:752:11
at TableauDeBordLayout (http://localhost:3232/app/routes/tableau-de-bord.tsx:9:18)
at RenderedRoute (http://localhost:3232/node_modules/.vite/deps/chunk-7GTNRECA.js?v=628cc138:401:5)
at Outlet (http://localhost:3232/node_modules/.vite/deps/chunk-7GTNRECA.js?v=628cc138:739:26)
at HoneypotProvider (http://localhost:3232/node_modules/.vite/deps/remix-utils_honeypot_react.js?v=628cc138:27:29)
at App (http://localhost:3232/app/root.tsx:199:7)
at body
at html
at Layout (http://localhost:3232/app/root.tsx:31:3)
at RenderedRoute (http://localhost:3232/node_modules/.vite/deps/chunk-7GTNRECA.js?v=628cc138:401:5)
at RenderErrorBoundary (http://localhost:3232/node_modules/.vite/deps/chunk-7GTNRECA.js?v=628cc138:361:5)
at DataRoutes (http://localhost:3232/node_modules/.vite/deps/chunk-7GTNRECA.js?v=628cc138:1394:5)
at Router (http://localhost:3232/node_modules/.vite/deps/chunk-7GTNRECA.js?v=628cc138:746:15)
at RouterProvider (http://localhost:3232/node_modules/.vite/deps/chunk-7GTNRECA.js?v=628cc138:1209:5)
at RemixErrorBoundary (http://localhost:3232/node_modules/.vite/deps/chunk-7GTNRECA.js?v=628cc138:2757:5)
at RemixBrowser (http://localhost:3232/node_modules/.vite/deps/chunk-7GTNRECA.js?v=628cc138:4294:46)
Hello @arnaudambro,
Assuming you're using the components exposed by react-dsfr, this error is very strange.
This attribute is added dynamically by the JavaScript code of @gouvfr/dsfr. This code isn't loaded on the backend during SSR. It cannot possibly be. If it was many errors would be thrown.
If you can produce a reproduction repo with precise steps to reproduce I'll be able to debug.
If you can produce a reproduction repo with precise steps to reproduce I'll be able to debug.
this is the repo I'm working on, with the code as is https://github.com/betagouv/zacharie/tree/24f0594140d20aa8d93f271947c8dd62fdb83112
the file your might be interested in is ./app/entry.client.tsx I think
Please provide the exact commands to reproduce and where I should navigate to reproduce the error.
git clone [email protected]:betagouv/zacharie.git
cd ./zacharie
git checkout 59b8832994911b2ce3523f8bee114048a6ddb8d2
yarn install
yarn dev-test-react-dsfr
this should work
I'm not getting the error described:
mmm yes, my bad, it's once you're logged in
then on the url http://localhost:3232/tableau-de-bord
if you remove everything except the header in ./app/tableau-de-bord.tsx you still get the error
import { Header } from "@codegouvfr/react-dsfr/Header";
export default function TableauDeBordLayout() {
return (
<>
<Header
brandTop={
<>
Ministère
<br />
de l'Agriculture
</>
}
homeLinkProps={{
href: "/",
title: "Zacharie - Ministère de l'Agriculture",
}}
id="fr-header-header-with-quick-access-items"
serviceTagline="La Fiche d’Examen Initial (FEI) simplifiée"
serviceTitle="Zacharie"
/>
</>
);
}
I made a branch for this test: https://github.com/betagouv/zacharie/tree/test--warning-dsfr
I still don't see the error you're refering to in this issue:
Hello, we're seeing similar warning in our project (only in dev mode) :
It can be reproduced on this PR : https://github.com/SocialGouv/code-du-travail-numerique/pull/6078
Run
yarn && yarn build
yarn dev:frontend
Then go to
http://localhost:3000/mentions-legales
Hello @carolineBda,
This is not the same error and not the same meta framwork. Please open a new issue.
ok :+1:
@carolineBda and unfortunatly, I can't reproduce either:
I still don't see the error you're refering to in this issue:
are you sure you're on the branch ? https://github.com/betagouv/zacharie/tree/test--warning-dsfr cause the error shows you need a postgres db but in that branch I removed the dependency to this - and it works fine on my computer
Yes. I was on the branch.
I'll try again after your update
Still can reproduce, neither with chrome or firefox, neither with network throtling.
The error I'm getting is:
I can look at this but this isn't the same error you're refering to, it's related to Remix Link component.
Maybe produce a dump of the error with https://www.replay.io/ ?
Maybe try clearing your browser cache as well.
It's maybe due to the fact that you've done this:
still here...
sorry I have no time right now to dig in a little bit more, but in October/November I think I'll be able to
Thanks anyway, great job done there !
This error appears when the lang attribute is set on the <DsfrProvider /> component and when using Next.js App router :
Here is a minimum layout to reproduce the error :
app/layout.tsx
import { type PropsWithChildren } from 'react';
import { DsfrProvider } from '@codegouvfr/react-dsfr/next-appdir/DsfrProvider';
import { getHtmlAttributes } from '@codegouvfr/react-dsfr/next-appdir/getHtmlAttributes';
import { StartDsfr } from '@/components/StartDsfr';
const RootLayout = ({ children }: PropsWithChildren) => {
return (
<html lang="fr" {...getHtmlAttributes({ defaultColorScheme: 'light', lang: 'fr' })}>
<head>
<StartDsfr />
</head>
<body>
<DsfrProvider lang="fr">{children}</DsfrProvider>
</body>
</html>
);
};
export default RootLayout;
For the
<StartDsfr />component see : https://react-dsfr.codegouv.studio/routing
Hello @lutangar, I doubt that is the root cause of the issue.
Here again I can't reproduce, I tried with the Next App Router Starter.
I'm down to fix whatever as long as you can provide me a reproduction path.
PS: getHtmlAttributes already sets the lang property so having lang="fr" {...getHtmlAttributes({ lang: 'fr' })} is redundant.
@garronej
I have such similar issue, but on my side it's an hydratation error between Server & Client.
Here is a reproduction of the problem https://github.com/mission-apprentissage/react-dsfr-next-appdir-demo/commit/971280055dd7c2f636aa14be305699075ec62b9d
That's a different error message, but I think it's all related to Suspense boundary
Hello,
Support for Next.js 15 just landed
Updated documentation:
https://react-dsfr.codegouv.studio/#next-js-app-router
Updated starter project:
https://github.com/garronej/react-dsfr-next-appdir-demo
Unfortunately, I couldn’t make it work without introducing breaking changes.
Please refer to the following commit to see what you’ll need to update:
https://github.com/garronej/react-dsfr-next-appdir-demo/commit/aaabb7925823fb163b83ffd438da7264084b629b
I had a build issue which is fixed with the latest relase, thanks!
But I'm still experiencing hydratation errors (https://github.com/mission-apprentissage/react-dsfr-next-appdir-demo)
@garronej what about creating Github release to add notes including potential breaking change ?
Yes sorry @moroine the hydratation error is still present. I'm looking into it.
Hello @moroine, @arnaudambro & @carolineBda,
I've made further updates to the Next App Router setup.
Please refer to the documentation here: https://react-dsfr.codegouv.studio/
The example setup (Next 15, React 19, using loading.tsx): https://github.com/garronej/react-dsfr-next-appdir-demo
The deployment of the example: https://react-dsfr-next-appdir-demo.vercel.app/
The Core Issue: Supporting SSR Streaming
The main challenge lies in how to support SSR streaming.
The @gouvfr/dsfr package was not designed with modern frameworks like Next.js in mind.
It relies on:
- A single CSS stylesheet
- A single JS module that is "started" when the DOM is fully ready
However, in a streaming SSR context, there’s no single point in time where the DOM is considered fully ready. Additional HTML chunks may be streamed later, as server components are progressively sent by the server.
This introduces a critical problem:
- Before DSFR is started, components are non-interactive
- After DSFR is started, any additional HTML streamed into the page may cause hydration errors, because DSFR will attempt to hydrate elements immediately as they appear in the DOM
There is no way within DSFR to:
- Selectively hydrate parts of the DOM
- Delay hydration until specific conditions are met
What This Means in Practice
As a result, I can’t abstract this logic away for you.
You must explicitly decide when the page is ready, and manually mount the component <StartDsfrOnHydration />.
Example usage:
src/app/page.tsx
import { StartDsfrOnHydration } from "../dsfr-bootstrap";
export default function Page() {
return (
<>
{/* Important: You must mount this component on every page of your app */}
<StartDsfrOnHydration />
<h1>Welcome!</h1>
</>
);
}
Important to Understand:
- Until
<StartDsfrOnHydration />is hydrated, DSFR elements remain non-interactive - Once it is hydrated, you can no longer stream in new HTML chunks conaining DSFR components (i.e. no server components below this point)
Your Options Moving Forward
You can choose between two strategies:
- Avoid SSR Streaming entirely — or only use it if you fully understand the implications and what will cause idration errors.
- Use DSFR components only for layout (e.g., header and footer), and rely on MUI components for the rest. Use
<MuiDsfrProvider>to maintain visual consistency.
I'm sorry this isn't more seamless — but unfortunately, this is the current state of things.
We have very limited influence over DSFR's development. DSFR 2.0 is not being built in the open, and I strongly suspect these architectural constraints won't be addressed anytime soon.
Let me know if anything is unclear.
@garronej what about creating GitHub releases to add notes, including potential breaking changes?
In my experience, very few people actually read release notes and we release too often.
Also, maintaining this project is already quite time consuming, and we've received zero support—past or present—from the SIG or DINUM.
That said, here’s what I can commit to:
- Ensuring compatibility with the latest version of Next.js.
- Keeping the documentation fully up to date.
- Keeping the starter project updated: https://github.com/garronej/react-dsfr-next-appdir-demo
- Avoiding silent breaking changes: if something breaks, it will trigger type errors.
Beyond that, I simply don't have the bandwidth to provide scheduled updates or detailed migration guides.