Support for react 19
+1 getting a warning too
react-helmet-async 2.0.5 └── ✕ unmet peer react@"^16.6.0 || ^17.0.0 || ^18.0.0": found 19.0.0
using it with react 19 and didn't see any issues so far. just complains about dependencies. so +1
react 19 have built-in support for metadata tags, see https://react.dev/blog/2024/12/05/react-19#support-for-metadata-tags This package is not needed anymore
For some reasons it stopped working when I updated to React 19.
I tested react-helmet-async and react-helmet, there were no errors or warning.
I ended up using React 19 meta tags
react 19 have built-in support for metadata tags, see react.dev/blog/2024/12/05/react-19#support-for-metadata-tags This package is not needed anymore
that's not 100% true
If you rely on some deduplication behavior that this lib provides, React 19 APIs are not a drop-in replacement. For example if I replaced helmet by React 19 APIs in the Docusaurus framework, we'd end up with duplicate head titles because we rely on "deeper" titles to override default titles defined in parent layout components.
There are other things that this library covers that React 19 don't, for example hosting classes / data attributes to the <html> or <body> tags
@slorber you not needed a library to do "`${defaultTitle} nested title`" templating. Actually this library can only replace parent title without any advanced templating.
This needs a new release for react 19. Shouldn't require anything but bumping the version in the package.json if there are not any breaking changes in react that impact this package.
react-helmet-async 2.0.5
└── ✕ unmet peer react@"^16.6.0 || ^17.0.0 || ^18.0.0": found 19.0.0
If anyone finds it helpful, Docusaurus is now running on my v1.3.0 fork, which allows React 19 as peerDeps: "react-helmet-async": "npm:@slorber/[email protected]",. No problem so far.
I didn't fork from v2 since I'm not sure what the breaking changes are. We'll upgrade the fork in the future.
Note: with React 19, I wonder if it's not time to create a new lib that would only be React 19+ and only implement the missing functionalities.
React 19 doesn't seem to handle even the most basic of use cases. We do not have any overriding of parent components
I see 4 issues here, asking for React 19 support, but no PRs. I'm not a front-end developer, so I cannot measure the complexity of this change: is it too complex for the community to develop it and propose the PR?
FYI, I got too annoyed by the lack of proper maintenance of this library, thus I forked it, changed the declared peer dependency for React to v19, and released it to NPM as a new package: https://www.npmjs.com/package/@dr.pogodin/react-helmet. At the moment there is no other changes in my fork, but I'm planning to revise its dependencies & implementation to ensure it is all up-to-date with the latest React features, and to take serious care about its proper maintenance going forward.
@birdofpreyru thank you so much. Please let me add something else too. For anyone who is waiting for this shitty repo to update itself, you can use a simple useEffect:
useEffect(() => {
const urls = [
"https://example.com/babel.min.js",
"https://example.com/react.development.js",
"https://example.com/react-dom.development.js",
"https://cdn.tailwindcss.com",
]
urls.forEach((url) => {
const script = document.createElement("script");
script.src = url;
script.async = true;
document.head.appendChild(script);
});
const style = document.createElement("style");
style.type = "text/tailwindcss";
style.textContent = tailwind;
document.head.appendChild(style);
}, [])
@Nefcanto if that's all you need for a page, I guess you may do even simpler just rendering and components as regular JSX — I haven't tried myself, but according to the React v19 documentation pages I linked, it is supposed to work.
I do think Helmet has some issues with React v19. eg: The title wont change if you switch to another page. Title only changes when you do a full refresh on that page. Idk if that just my code problem or what. So I downgraded to React v18.3.1, and Helmet works, problem solved...
For those getting a warning or don't want to everytime run an npm i --force add this to package.json:
"overrides": { "react-helmet-async": { "react": "^19.0.0", "react-dom": "^19.0.0" } }
Option 1: Use --legacy-peer-deps (recommended for now) This tells npm to install it anyway and ignore the peer conflict:
npm install react-helmet-async --legacy-peer-deps
✅ Works in most cases if the package still functions fine under React 19 (which it probably does unless there are breaking changes).
Option 2: Use --force (riskier)
npm install react-helmet-async --force
This forces npm to install it no matter what. But be careful — this can break stuff if the library really isn't compatible.
TIL that the UnJS ecosystem has a new @unhead/react package 🥳 thanks @harlan-zw
https://unhead.unjs.io/docs/react/head/guides/get-started/installation
From the PR: https://github.com/unjs/unhead/pull/477
It can directly replace react-helmet, handling a more diverse set of use cases from SEO to structured data.
If you give it a try, please share feedback and tell us if it's also a great way to replace react-helmet-async
@slorber @dr.pogodin/react-helmet — my re-worked fork of react-helmet-async is the great way to replace either react-helmet-async, or the original react-helmet 😉
@birdofpreyru, having multiple options is fine. I don't really see the point of 👎 my comment.
Personally, I like to adopt libs under the UnJS organization, which are generally well-maintained over time by more than a single contributor.
I also like their promise of The full stack <head> package for any framework.. In other UnJS ecosystem packages, they successfully delivered on that framework-agnostic promise, sharing relevant code between frameworks, and we already use some of them in Docusaurus.
Also, both projects have different licenses (Unhead is MIT, yours is Apache 2), which may matter for some organizations.
Both options can be relevant for different people, and people should be aware of both. I still have no idea if @unhead/react works great, but at least it's worth giving it a try and reporting here.
having multiple options is fine. I don't really see the point of 👎 my comment.
Well, I just have invested my time, hence my money, into refactoring react-helmet-async to correctly work with the latest React and stuff, while conserving the original API & behavior, to make updates seamless. Any suggestion that something else should be explored & preferred, just because backed by a larger org, reads to me like a suggestion that outcome of my work & investment does not deliver on its promise, thus pisses me off 🤷♂
Someone else also invested time/money, before you, to provide React-Helmet compatibility:
- https://github.com/unjs/unhead/pull/477
- https://unhead.unjs.io/docs/react/head/guides/get-started/migrate-from-react-helmet
I don't want to dismiss your work, but it's not fair to reject other possible options as if your fork was the "official way" to replace this lib.
People can make their own judgment based on various factors, including backing by a larger org/company, license, reputation of the authors, community feedback, npm downloads, quality of the docs, project governance, security risk of supply chain attack, and whatever else.
Someone else also invested time/money, before you, to provide React-Helmet compatibility.
A brief look at someone else's profile, and it looks quite clear, that he got paid by Nuxt & Co to do the job, in their quest to suffocate independent developers & projects, to create market & demand for their own web framework and developers.
It also must feel quite awesome to him that although he did not bother to do any effort to announce his work, so that react-helmet(-async) users could actually find it, his fanboys go around and promote their lib.
your fork was the "official way" to replace this lib.
I'll just underline it again — my fork takes the original API, logic, etc. and updates the code and dependencies to the current-day versions & best practices, thus it is as seamless replacement of react-helmet(-async) as possible. No way an independently developed library unjs/unhead, with some compatibility patches, can be the same good replacement (unless they have copy/pasted their core-logic from react-helmet, and just ignored the original Apache 2 license, replacing it by MIT). I hope, people will do the right judgment here 😃
Hey @birdofpreyru. I'm not too sure where this hostility is coming from, but I hope we can move past it, as I don't think it's productive or called for.
Let me clarify a few things.
A brief look at someone else's profile, and it looks quite clear, that he got paid by Nuxt & Co to do the job, i
The only money I make from open-source is through GitHub sponsors, Nuxt Labs sponsors me $250 USD / month. I maintain several modules in the Nuxt ecosystem, which are unrelated to this package, not that it would have any bearing anyway.
The project is published under the UnJS ecosystem so it can grow beyond me as an individual.
It also must feel quite awesome to him that although he did not bother to do any effort to announce his work, so that react-helmet(-async) users could actually find it, his fanboys go around and promote their lib.
Tweet: https://x.com/harlan_zw/status/1904190799295963552, announcement post: https://unhead.unjs.io/v2.
The docs have been specifically written for react-helmet users looking to migrate, hence why this page was released with the v2 https://unhead.unjs.io/docs/react/head/guides/get-started/migrate-from-react-helmet.
I'd rather not tell people what to use, if they discover it organically and they think it's a good fit then they can try it out themselves. If it solves a problem, people will share it and it will grow.
No way an independently developed library unjs/unhead, with some compatibility patches, can be the same good replacement
Unhead supercedes react-helmet in many ways because it was written from scratch around the constraints discovered through early projects like React Helmet. It also looks to capture more value by providing higher-level SEO APIs that end users are asking for and don't want to have to use Next.js to get.
@harlan-zw no hostility at all, we just clearly have different agenda and points of view on what is good for ecosystem 😉 it is not personal 😃
The only money I make from open-source is through GitHub sponsors, Nuxt Labs sponsors me $250 USD / month. I maintain several modules in the Nuxt ecosystem, which are unrelated to this package, not that it would have any bearing anyway.
The project is published under the UnJS ecosystem so it can grow beyond me as an individual.
Well, I was not there to witness what is the actual deal between you and Nuxt. But looking up the info about Nuxt and UnJS I read right away that Nuxt is based on top of UnJS, thus I guess Nuxt is the driving force behind UnJS, and the main reason behind the split of Nuxt and UnJS is to keep the bulk of Nuxt source code as seemingly independent, free, open-source, to easier attract developers to contribute, for free, to, in the end, Nuxt business success — that's why such stuff is done — cold business strategies hidden behind human-friendly arguments and wishful thinking that it is all done for free, for the pure love of the community.
Otherwise, there is already a long-standing popular react-helmet library. Anybody having any issues with its performance or features can easily contribute into its evolution, and if the owner disappears, then it can be forked and thus continued — that's what react-helmet-async author did, and what I did now. That is what is actually good for the community, for the stability and gradual evolution of long-term projects. People who re-invent the wheel, and choose to write a new independent library when there is no real need to, they have a different agenda.
✅ React 19 adds a support for rendering document metadata tags in components natively, so no need to use "react-helmet-async" any more! This is a sample example of that, I just bmake a compponent named 'Meta.jsx' , and i used it where i needed:
const Meta = ({ title, description, keywords }) => { return <>
Meta.defaultProps = { title: 'Welcome', description: 'We sell the best products for cheap', keywords: 'electronics, buy electronics, cheap electronics', }
export default Meta;
@anouar4070 🤣 🤣 🤣 do you seriously think that ppl who bother creating, forking, and maintaining react libraries, do not read release notes for major react releases? 🤣 🤣 🤣
Try rendering the title multiple times with your component, see what happens in DOM, and compare that to what happens to DOM when you do the same using Helmet :)
Try rendering the title multiple times with your component, see what happens in DOM, and compare that to what happens to DOM when you do the same using Helmet :)
Or simply have a title set by your index html and then use react to change that title. it will inject another title tag instead of removing the already existing one. that's why it would be good to have helmet work smoothly again.
@lhtdesignde if you're just using Helmet for setting titles, copy/pasting these 10 lines of code into your project works perfectly fine: https://github.com/witoszekdev/react-simple-page-title/blob/main/src/usePageTitle.ts