99

I was working on a single page application in react.js, so what is the best way to update meta tags on page transitions or browser back/forward?

14 Answers 14

53

I've used react-document-meta in an older project.

Just define your meta values

const meta = {
    title: 'Some Meta Title',
    description: 'I am a description, and I can create multiple tags',
    canonical: 'http://example.com/path/to/page',
    meta: {
        charset: 'utf-8',
        name: {
            keywords: 'react,meta,document,html,tags'
        }
    }

and place a

<DocumentMeta {...meta} />

in the return

Sign up to request clarification or add additional context in comments.

7 Comments

will tags change with the page transitions or only for the landing page?
How is your application structured? Do you have multiple components or just one which gets changed while transitioning?
2 components would change, rest remain same.
Also I am seeing this module is no longer active github.com/skevy/react-document-meta . Is the one mentioned in link and one mentioned by you the same?
I've tried all three modules: react-document-meta, react-meta-tags, and react-helmet. The first appears to have been abandoned. The second does not support React 18 and maybe even 17. That left react-helmet. The first and last both have issues with deprecated component mount routines that are logged in the browser console.
|
46

You almost definitely want to use:

React Helmet

In contrast to react-meta-tags it can nest <Helmet>s and so you can define your meta tags deep within your app - like <title>s that should override each other. And in contrast to react-document-meta you can define things using jsx (and nest things).

This seems to be the solution that the community almost exclusively uses - 600,000 weekly downloads vs the 6,000 given in other solutions. "Helmet takes plain HTML tags and outputs plain HTML tags. It's dead simple, and React beginner friendly." - and has support for server-side rendering.

Here's an example, adapted from the front page:

<Parent>
    I'm a parent
    <Helmet>
        <title>My Title</title>
        <meta name="description" content="Helmet application" />
    </Helmet>
 
    <Child>
        I'm a child
        <Helmet>
            <title>Nested Title</title>
            <meta name="description" content="Nested component" />
        </Helmet>
    </Child>
</Parent>

outputs:

<head>
    <title>Nested Title</title>
    <meta name="description" content="Nested component">
</head>
<Parent>
    I'm a parent
    <Child>
        I'm a child
    </Child>
</Parent>

5 Comments

Helmet is great. Your argument is ad populum, however, and you haven't shown any code.
will react helment make my page to index on google since I have added meta tags and description?
where should i add this in my React component?
It hasn't been updated since 3 years. Is it still relevant?
@FTW , i thought the same but then it has around 2 MILLION weekly downloads so im guessing the package just maxed out and is too good to be upgraded
42

You can use react-meta-tags. It allows you to write title and other meta tags in a declarative way and in normal jsx format, which will be moved to head (Check server usage on the doc).

import React from 'react';
import MetaTags from 'react-meta-tags';

class Component1 extends React.Component {
  render() {
    return (
        <div class="wrapper">
          <MetaTags>
            <title>Page 1</title>
            <meta id="meta-description" name="description" content="Some description." />
            <meta id="og-title" property="og:title" content="MyApp" />
            <meta id="og-image" property="og:image" content="path/to/image.jpg" />
          </MetaTags>
          <div class="content"> Some Content </div>
        </div>
      )
  }
}

You may also like to check react-helmet if you have an advanced use case.

5 Comments

I had an issue with duplicate metatags while trying to use react-meta-tags. react-helmet did not duplicate tags on route or state change.
This has been fixed now.
@SudhanshuYadav Still not fixed. Just tried og:title and og:image
@SudhanshuYadav i know been a long time since this post, but I am facing this issue, I see meta tags when I inspect element, but it doesn't show on page source. Is there any way We can generate dynamic tags and show them in page source.
Not clear if it supports things like header tags which is important for SEO.
19

You cand also give the page title and meta tags description in the following way.

place a meta tag of description in your index.html file like this.

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<title>Dynamic Page title here</title>

in your .js files or .jsx files below the render() method write the page title and meta description for the page like this .

render()
{
document.title ="Welcome | here is your page title to display"; 
document.getElementsByTagName("META")[2].content="Your description about the page or site here to set dynamically";

return(
    <div>Page content</div>
);
}

5 Comments

I can see my meta tags being updated using this approach, but when I use twitter card validator or facebook share debugger, it doesn't find my meta/opengraph tags :( Note : I am static hosting
Or you can just use getElementsByName to be more specific by targeting by the element's name
This is not going to work. Because document is a javascript code and search crawler cant read javascript
Just a small tip that worked for me (working in SSR architecture. I put this on the componentDidMount() method.
For some reason, the meta tags end up in the html body instead of the head
11

Firstly if you don't need dynamic data you can just edit public/index.html.

For dynamic data the React team recommends to either use react-helmet

import React from "react";
import { Helmet } from "react-helmet";

class Application extends React.Component {
  render () {
    return (
        <div className="application">
            <Helmet>
                <meta charSet="utf-8" />
                <title>React app</title>
                <meta name="description" content="React application" />
            </Helmet>
            ...
        </div>
    );
  }
};

Or using placeholders and replacing them server-side:

<html lang="en">
  <head>
    <meta property="og:title" content="__OG_TITLE__" />
    <meta property="og:description" content="__OG_DESCRIPTION__" />
  </head>
</html>

2 Comments

Can you share the method how to replacing them on server-side
7

You can use the document query and update their values.

const setTitle = title => {
    const el = document.querySelector('title');
    el.innerText = `${el.text} | ${title}`;
  };

const setDescription = desc => {
    const el = document.querySelector("meta[name='description']");
    el.setAttribute('content',desc)
  }

Comments

6

According to the official documentation React Doc - Title and Meta Tags, you can also use React Helmet

2 Comments

This library is quite behind. They use deprecated lifecycle hooks...
@mmla at the time of that comment, Hooks were introduced only two (!) months prior...
3

As create-react-app docs mentioned:

If you need to dynamically update the page title based on the content, you can use the browser document.title API. For more complex scenarios when you want to change the title from React components, you can use React Helmet, a third party library.

A simple example:

function App(){
  document.title = "Home";
  return (
   <div>...</div>
  )
}

1 Comment

This didn't work for me, but @Fahd Allebdi's solution did.
1

https://react.dev/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023#document-metadata

there will be no need for external tools.

"This is why we’re adding built-in support for rendering , , and metadata tags anywhere in your component tree out of the box. It would work the same way in all environments, including fully client-side code, SSR, and in the future, RSC. We will share more details about this soon."

1 Comment

Example of implementation of it?
0

Maybe it's late but you can do this very simply like this:

Just use useEffect() in your component like:

useEffect(() => {
  document.head.innerHTML+=`
  <meta name='description' content='My description value!!!'/>
  <meta name='keywords' content='My keywords!!!'/>
  `
}, []);

1 Comment

This will append to the innerHTML every time the useEffect is called. This is not what you want.
0

I will supplement the answers for React with Vite projects, property="og:image". Maybe it will be useful to someone)

  1. place the image in the root folder /public

  2. in index.html add:

    <meta property="og:image" content="https://yourWebSite.net/yourImage.png" />

Comments

0

There is one more solution for this issue - unhead - that should supposedly work for any framework and well maintained. There are two changes you need to make:

  1. Create the head client in the root
import {createHead} from "unhead";

const App = () => {
    createHead();

    return (
        <BrowserRouter>
          <Routes>
              <Route path="/about" element={<About/>}/>
          </Routes>
        </BrowserRouter>
    );
};
  1. Use wherever you need
import {useHead} from "unhead";

useHead({
    meta: [
        { name: "description", content: "About page" },
    ],
});

Comments

-1

Not sure if this is the answer you were looking for but I was searching for how to update the info your react app shows when you preview the link in some other app. Every solution I tried wasn't working with github pages and react (react-helmet, react-meta-tags, react-document-meta). What ended up working was that you can edit the index.html located inside the public folder to change this info. Include this somewhere in the head:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/IMDB.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <title>IMDB</title>
    <meta property="og:audio" content="http://example.com/bond/theme.mp3" />
    <meta property="og:description" 
      content="Sean Connery found fame and fortune as the
               suave, sophisticated British agent, James Bond." />
    <meta property="og:determiner" content="the" />
    <meta property="og:locale" content="en_GB" />
    <meta property="og:locale:alternate" content="fr_FR" />
    <meta property="og:locale:alternate" content="es_ES" />
    <meta property="og:site_name" content="IMDb" />
    <meta property="og:video" content="http://example.com/bond/trailer.swf" />

Example from https://ogp.me/

1 Comment

Man that's like shitting on reactjs anyway upvote cuz it's not so bad after all
-1

You can use querySelector to access the tags and change the attribute value from it.

useEffect(()=>{
document.title="Page Title"
let descMeta=document.querySelector("meta[name='description']")
descMeta.setAttribute("content", 'Description of your page')
let themeMeta=document.querySelector("meta[name='theme-color']")
themeMeta.setAttribute("content", "#ffffff")
},[])

This is one way you can change the title and other tags from head.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.