Skip to content

Duplicate title tag with React 19 #266

Description

@w3bStuff

My app has been using react 19 for a while and I recently upgraded react-helmet-async from version 2.0.5 to 3.0.0.
As a result my current logic that uses a <HelmetProvider> with a default <Helmet> component that sets a titleTemplate doesn't work any more.
Every single page of my SPA calls my custom component <CustomHelmet> that in turn sets the page title an meta data by calling <Helmet>:

export const CustomHelmet = (props: CustomHelmetProps) => {
  const applicationUrl = window?.location?.origin || "";
  const absoluteUrl = props.url?.startsWith("/")
    ? `${applicationUrl}${props.url}`
    : props.url;

  const location = useLocation();
  const currentUrl = `${applicationUrl}${location.pathname}`;

  return (
    <Helmet key={props.title}>
      {/* Standard metadata tags */}
      <title>{props.title}</title>
      <meta name="description" content={props.description} />
      <link rel="canonical" href={absoluteUrl ?? currentUrl} />

      {/* Facebook tags */}
      <meta property="og:type" content={props.type || "website"} />
      <meta property="og:title" content={props.title} />
      <meta property="og:description" content={props.description} />
      <meta property="og:url" content={absoluteUrl ?? currentUrl} />

      {/* Twitter tags */}
      <meta name="twitter:creator" content={props.name} />
      <meta name="twitter:card" content={props.type || "website"} />
      <meta name="twitter:title" content={props.title} />
      <meta name="twitter:description" content={props.description} />
    </Helmet>
  );
};

As a result of the upgrade, and as stated in the doc, "HelmetProvider becomes a transparent passthrough." and "Helmet renders actual DOM elements and lets React handle hoisting them to head".

My issue is that my SPA loads off a static HTML file that also contains a placeholder title tag. Once the app kicks in and a page is displayed, I end up with two <title> tags in my HTML <head>: the placeholder title tag and the custom one set in the page.

How to recover the previous behaviour without downgrading back to v2?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions