DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for Dynamic document head with React Helmet
guim
guim

Posted on

Dynamic document head with React Helmet

Helmet is a React component that allows us to manage all of the changes to the document head. For example, let's say we're doing a social network. On the main page we may want the website title something like "My Social Network", but if we go to a user's profile the title should look like this: "User's name/Id - My Social Network".

Usage example

import React from 'react';
import { Helmet } from 'react-helmet';
import { Switch, Route } from 'react-router-dom';

import PageOne from 'containers/PageOne';
import PageTwo from 'containers/PageTwo';

const App = () => (
  <div className="app">
    <Helmet>
      <title>My App</title>
      <meta charSet="utf-8" />
      <meta name="description" content="A React.js application" />
    </Helmet>
    <Switch>
      <Route exact path="/" component={PageOne} />
      <Route path="/page-2" component={PageTwo} />
    </Switch>
  </div>
);

export default App;

Here's an example of a very basic app. As we can see, the title of the page will be My App. But this app has different routes. Let's say we want to change the title and the description for the /page-2 route, but we want to maintain the charset encoding. We can easily do it like this:

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

export default class PageTwo extends React.Component {
  <div className="page-two">
    <Helmet>
      <title>Page 2</title>
      <meta name="description" content="This is a different description for this route." />
    </Helmet>
    <h1>Page 2</h1>
  </div>
);

As we only defined the title and the description in this second component, they'll be the only two values overwritten from the app itself. The charset won't change as we didn't define a new one.

The output title of this example is: Page 2

Using templates and default title

We can go a step ahead and make use of the properties that Helmet provides to us. For example the titleTemplate and the defaultTitle. We'll repeat the example above but now we'll establish these two props in the App's head.

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

const App = () => (
  <div className="app">
    <Helmet titleTemplate="%s - My App" defaultTitle="My App">
      <meta name="description" content="A React.js aapplication" />
    </Helmet>
    <h1>My App</h1>
  </div>
);

export default App;

At this point, if we change to another component and we don't change the title, as the default title is My App this will be the output. Let's change it with the PageTwo component like before.

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

export default class PageTwo extends React.Component {
  <div className="page-two">
    <Helmet>
      <title>Page 2</title>
      <meta name="description" content="This is a different description for this route." />
    </Helmet>
    <h1>Page 2</h1>
  </div>
);

Now the output title will be Page 2 - My App since we established the template. The %s is substituted by the string we pass on the title tag.

This is a very easy tutorial but I think it's very helpful for those who didn't know this component. Hope you enjoyed it! If you have any doubt leave it in the comments below. You can read the whole documentation in their Github.

Top comments (10)

Collapse
 
banjer71 profile image
Davide Naccarati

Do I have to remove all the meta tag from index.html file? Or Helmet simply will overwrite everything?
I tried to do the basic example and it works, but when I copy and paste the link in Whatsapp or slack it still show the react logo and the description "website created with react etc..."

Collapse
 
ngesbrian profile image
NgesBrian

Did you ever get a response to this question or got a way around it ? I am desperately in need of this solution

Collapse
 
banjer71 profile image
Davide Naccarati

No, I did not but if you are using create-react-app it won't work. You need gatsby o nextJS to make it work because they are SSR Server-Side-Rendering and that kind of things I was looking for it works only with SSR.

Collapse
 
ravirize profile image
Ravi Sharma • Edited on

I have declared a meta tag with keyword in index.html, now i am trying to override the keyword from specific component by using react-helmet but it is not updating keywords from specific component, it always displays the content of index.html instead of specific component where i have updated the meta tag content.
Can any one help me out of this.
Thank you.

Collapse
 
aleksacupic profile image
AleksaCupic

If you use SSR it should work fine. However, If you render it on client it will always read index.html meta tags first.

Collapse
 
ngesbrian profile image
NgesBrian

so how do I make my react application with PHP API to be able to change that information for every single page

Collapse
 
adventurebear profile image
Suzanne Atkinson

Does this still work when using partials ? It seems like helmet should go in the head, but when the page is rendered it's already in the HTML body. I guess I can try but I can't find documentation on it.

Collapse
 
thusharsoyam profile image
Thushar-Soyam • Edited on

Currently, I am using meta tags inside the js file with the react-helmet. It gives me the meta tags nodes while inspecting the element, but when I view the page source code or while trying to share my links in any social media like Facebook or Twitter, I am getting only the values in the index.html file. I want to have a separate set of meta tags on each page. How can I do that?

all pages view page source showing same

<!DOCTYPE html>








<br> window.dataLayer = window.dataLayer || [];<br> function gtag(){dataLayer.push(arguments);}<br> gtag(&#39;js&#39;, new Date());</p> <div class="highlight"><pre class="highlight plaintext"><code>gtag('config', 'UA-145453700-1'); </code></pre></div> <p>

Please help me in that, this in the website link ...instavc.com/

Collapse
 
ockkk profile image
Hwang Jongock

Thank you for your good article. Thank you for your good article. If you don’t mind, can I translate this into Korean and see the people who study with me?

Collapse
 
abbiranjan profile image
Alok Ranjan

Very nicely explained.
Actually looking for this kind of detailed and easy to understand explanation.

Thanks a lot...

🌚 Life is too short to browse without dark mode