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)
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..."
Did you ever get a response to this question or got a way around it ? I am desperately in need of this solution
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.
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.
If you use SSR it should work fine. However, If you render it on client it will always read index.html meta tags first.
so how do I make my react application with PHP API to be able to change that information for every single page
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.
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('js', 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/
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?
Very nicely explained.
Actually looking for this kind of detailed and easy to understand explanation.
Thanks a lot...