React Helmet is a component to dynamically manage the document’s head
section. Some common use cases include setting the title
, description
, and meta
tags for the document.
When combined with server-side rendering, it allows you to set meta
tags that will be read by search engines and social media crawlers. This makes server-side rendering and React Helmet a powerful combination for creating apps that can benefit from SEO (search engine optimization) and social media data like oEmbed, Facebook Open Graph, or Twitter Cards.
In this article, you will explore the functionality of React Helmet in a React application.
To follow along with this article, you will need:
npm
or yarn
.Note: This tutorial will not cover the steps for creating a React project or setting up server-side rendering. Please refer to How to Enable Server-Side Rendering for a React App.
This tutorial was verified with Node v15.3.0, npm
v6.14.9, react
v17.0.1, and react-helmet
v6.1.0.
First, install the component into your project:
- npm install react-helmet@6.1.0
Now you can use React Helmet in your app by adding the elements that should go in the head of the document as children to the Helmet
component:
import { Helmet } from 'react-helmet';
function App() {
return (
<div className="App">
<Helmet>
<title>App Title</title>
<meta name="description" content="App Description" />
<meta name="theme-color" content="#008f68" />
</Helmet>
</div>
);
}
export default App;
Then, open your browser’s developer tools and inspect the head
element:
Inspect Element<head>
<!-- ... --->
<title>App Title</title>
<!-- ... -->
<meta name="description" content="App Description" data-react-helmet="true">
<meta name="theme-color" content="#008f68" data-react-helmet="true">
<!-- ... --->
</head>
Observe the title
and meta
elements added by React Helmet.
Components further down the tree can override values provided to the Helmet
component on a higher level.
For example, consider a ChildComponent
that contains a Helmet
component that modifies title
:
import React from 'react';
import { Helmet } from 'react-helmet';
export default function ChildComponent() {
return (
<div>
<Helmet>
<title>Modified Title</title>
</Helmet>
<h1>Child Component</h1>
</div>
)
}
Next, revisit App
component and include the new ChildComponent
:
import { Helmet } from 'react-helmet';
import ChildComponent from './ChildComponent';
function App() {
return (
<div className="App">
<Helmet>
<title>App Title</title>
<meta name="description" content="App Description" />
<meta name="theme-color" content="#008f68" />
</Helmet>
<ChildComponent />
</div>
);
}
Then, open your browser’s developer tools and inspect the head
element:
Inspect Element<head>
<!-- ... --->
<title>Modified Title</title>
<!-- ... -->
<meta name="description" content="App Description" data-react-helmet="true">
<meta name="theme-color" content="#008f68" data-react-helmet="true">
<!-- ... --->
</head>
The title
will be changed from App Title
to Modified Title
. The meta
tags for description
and theme-color
values will remain the same because they have not been overwritten.
html
and body
You can even include the html
and body
elements if you need to specify attributes for them.
For example, consider a body
element that has a dark
theme applied to it:
import { Helmet } from 'react-helmet';
function App() {
return (
<div className="App">
<Helmet>
<title>App Title</title>
<meta name="description" content="App Description" />
<meta name="theme-color" content="#008f68" />
<body class="dark" />
</Helmet>
</div>
);
}
Then, open your browser’s developer tools and inspect the body
element:
[seconday_label Inspect Element]
<body class="dark" data-react-helmet="class">
<!-- ... -->
</body>
The class
will be set to dark
.
The full benefit of React Helmet becomes apparent when the app is rendered on the server so that the app gets served with the correct elements in the head of the document.
Assuming that you have a React server-side rendered app setup in place, you can call React Helmet’s renderStatic
method right after calling ReactDOMServer’s renderToString
or renderToStaticMarkup
to get an instance with properties for the Helmet
data:
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import express from 'express';
import { Helmet } from 'react-helmet';
import App from '../src/App';
const PORT = process.env.PORT || 3006;
const app = express();
app.get('/*', (req, res) => {
const appString = ReactDOMServer.renderToString(<App />);
const helmet = Helmet.renderStatic();
const html = `<!DOCTYPE html>
<html lang="en">
<head>
${helmet.title.toString()}
${helmet.meta.toString()}
</head>
<body>
<div id="root">
${ appString }
</div>
</body>
</html>
`
res.send(html);
});
app.listen(PORT);
Calling Helmet’s renderStatic
returns an instance with properties like title
and meta
. You will also have access to other properties like link
, script
, noscript
, style
, htmlAttributes
, and bodyAttributes
.
react-helmet-async
As brought up here by @mxstbr from Spectrum, React Helmet works synchronously which can potentially lead to issues on the server, especially with streaming.
A fork of React Helmet comes to the rescue: react-helmet-async
.
- npm install react-helmet-async@1.0.7
The API is the same, with the exception that a HelmetProvider
needs to wrap the component tree on both the client and the server:
import Helmet, { HelmetProvider } from 'react-helmet-async';
function App() {
return (
<HelmetProvider>
<div className="App">
<Helmet>
<title>App Title</title>
<meta name="description" content="App Description" />
<meta name="theme-color" content="#008f68" />
</Helmet>
</div>
/HelmetProvider>
);
}
More information on the intent and usage of React Helmet Async is available on the announcement post on the New York Times Open blog.
In this article, you explored the functionality of React Helmet in a React application. Particularly how it works well with server-side rendering for promoting SEO and social media integrations.
If you’d like to learn more about React, take a look at our How To Code in React.js series, or check out our React topic page for exercises and programming projects.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Thank you so much.