react-helmet-async icon indicating copy to clipboard operation
react-helmet-async copied to clipboard

Support for react 19

Open pouyaafraz123 opened this issue 1 year ago • 29 comments

pouyaafraz123 avatar Dec 12 '24 10:12 pouyaafraz123

+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

gvillo avatar Dec 13 '24 15:12 gvillo

using it with react 19 and didn't see any issues so far. just complains about dependencies. so +1

lhtdesignde avatar Dec 16 '24 14:12 lhtdesignde

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

vitalyster avatar Dec 27 '24 16:12 vitalyster

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

phoenixstudiodz avatar Dec 28 '24 11:12 phoenixstudiodz

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

CleanShot 2024-12-30 at 17 23 58

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.

CleanShot 2024-12-30 at 17 24 48


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 avatar Dec 30 '24 16:12 slorber

@slorber you not needed a library to do "`${defaultTitle} nested title`" templating. Actually this library can only replace parent title without any advanced templating.

vitalyster avatar Dec 30 '24 20:12 vitalyster

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.

KyleJune avatar Jan 01 '25 20:01 KyleJune

react-helmet-async 2.0.5
  └── ✕ unmet peer react@"^16.6.0 || ^17.0.0 || ^18.0.0": found 19.0.0

antonio-ivanovski avatar Jan 08 '25 10:01 antonio-ivanovski

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.

slorber avatar Jan 17 '25 10:01 slorber

React 19 doesn't seem to handle even the most basic of use cases. We do not have any overriding of parent components

by child components <title>. However our root HTML file (index.html that loads React) does contain a default <title> tag so that the user sees a title while React is loading. Even in this case, the <title> tag gets duplicated by React 19 once the component loads, and the browser tends to keep the first one, so it is not really usable in practice and Helmet remains very necessary.

laug avatar Jan 31 '25 22:01 laug

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?

kkovaletp avatar Feb 01 '25 07:02 kkovaletp

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 avatar Feb 22 '25 18:02 birdofpreyru

@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 avatar Mar 10 '25 11:03 Nefcanto

@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.

birdofpreyru avatar Mar 11 '25 00:03 birdofpreyru

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...

Norlandz avatar Apr 04 '25 14:04 Norlandz

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" } }

mbdev3 avatar Apr 15 '25 19:04 mbdev3

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.

swapnilahmedshishir avatar Apr 17 '25 18:04 swapnilahmedshishir

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 avatar May 02 '25 08:05 slorber

@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 avatar May 02 '25 09:05 birdofpreyru

@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.

slorber avatar May 02 '25 10:05 slorber

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 🤷‍♂

birdofpreyru avatar May 02 '25 11:05 birdofpreyru

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.

slorber avatar May 02 '25 15:05 slorber

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 😃

birdofpreyru avatar May 02 '25 16:05 birdofpreyru

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 avatar May 04 '25 09:05 harlan-zw

@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.

birdofpreyru avatar May 04 '25 14:05 birdofpreyru

✅ 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 <>

{title} </>; };

Meta.defaultProps = { title: 'Welcome', description: 'We sell the best products for cheap', keywords: 'electronics, buy electronics, cheap electronics', }

export default Meta;

anouar4070 avatar May 09 '25 21:05 anouar4070

@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 :)

birdofpreyru avatar May 10 '25 14:05 birdofpreyru

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 avatar May 12 '25 07:05 lhtdesignde

@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

laug avatar May 31 '25 12:05 laug