What is react-helmet-async?
The react-helmet-async package is a reusable React component that manages changes to the document head, allowing developers to dynamically set the contents of the head section of the page, which includes the title, meta tags, and other elements. It is a thread-safe version of react-helmet that works well with server-side rendering.
What are react-helmet-async's main functionalities?
Setting the page title
This feature allows you to set the title of the page dynamically. The title tag inside the Helmet component will update the document's title when the component is rendered.
{"<Helmet><title>My Page Title</title></Helmet>"}
Managing meta tags
With this feature, you can manage meta tags such as the description, keywords, and others. This is particularly useful for SEO purposes and for providing metadata for social media platforms.
{"<Helmet><meta name='description' content='Page description' /></Helmet>"}
Adding link tags
This feature allows you to add link elements to the head, which can be used for defining canonical URLs, linking to stylesheets, or adding a favicon.
{"<Helmet><link rel='canonical' href='http://mysite.com/example' /></Helmet>"}
Adding script tags
You can dynamically add script tags to the head of the document, which is useful for including external JavaScript files or inline scripts.
{"<Helmet><script src='http://include.com/pathtojs.js' type='text/javascript' /></Helmet>"}
Other packages similar to react-helmet-async
react-helmet
This is the predecessor of react-helmet-async. It offers similar functionality for managing the document head, but it is not thread-safe and can have issues with server-side rendering in concurrent mode.
next-seo
A plugin for Next.js projects that provides a set of SEO components and helpers. It is similar to react-helmet-async but is specifically tailored for Next.js and includes additional SEO features.
react-meta-tags
A lightweight package for managing HTML meta tags in React applications. It is similar to react-helmet-async but with a simpler API and less overhead.
react-helmet-async
Announcement post on Times Open blog
This package is a fork of React Helmet.
<Helmet>
usage is synonymous, but server and client now requires <HelmetProvider>
to encapsulate state per request.
react-helmet
relies on react-side-effect
, which is not thread-safe. If you are doing anything asynchronous on the server, you need Helmet to encapsulate data on a per-request basis, this package does just that.
Usage
New is 1.0.0: No more default export! import { Helmet } from 'react-helmet-async'
The main way that this package differs from react-helmet
is that it requires using a Provider to encapsulate Helmet state for your React tree. If you use libraries like Redux or Apollo, you are already familiar with this paradigm:
import React from 'react';
import ReactDOM from 'react-dom';
import { Helmet, HelmetProvider } from 'react-helmet-async';
const app = (
<HelmetProvider>
<App>
<Helmet>
<title>Hello World</title>
<link rel="canonical" href="https://www.tacobell.com/" />
</Helmet>
<h1>Hello World</h1>
</App>
</HelmetProvider>
);
ReactDOM.hydrate(
app,
document.getElementById(‘app’)
);
On the server, we will no longer use static methods to extract state. react-side-effect
exposed a .rewind()
method, which Helmet used when calling Helmet.renderStatic()
. Instead, we are going
to pass a context
prop to HelmetProvider
, which will hold our state specific to each request.
import React from 'react';
import { renderToString } from 'react-dom/server';
import { Helmet, HelmetProvider } from 'react-helmet-async';
const helmetContext = {};
const app = (
<HelmetProvider context={helmetContext}>
<App>
<Helmet>
<title>Hello World</title>
<link rel="canonical" href="https://www.tacobell.com/" />
</Helmet>
<h1>Hello World</h1>
</App>
</HelmetProvider>
);
const html = renderToString(app);
const { helmet } = helmetContext;
Streams
This package only works with streaming if your <head>
data is output outside of renderToNodeStream()
.
This is possible if your data hydration method already parses your React tree. Example:
import through from 'through';
import { renderToNodeStream } from 'react-dom/server';
import { getDataFromTree } from 'react-apollo';
import { Helmet, HelmetProvider } from 'react-helmet-async';
import template from 'server/template';
const helmetContext = {};
const app = (
<HelmetProvider context={helmetContext}>
<App>
<Helmet>
<title>Hello World</title>
<link rel="canonical" href="https://www.tacobell.com/" />
</Helmet>
<h1>Hello World</h1>
</App>
</HelmetProvider>
);
await getDataFromTree(app);
const [header, footer] = template({
helmet: helmetContext.helmet,
});
res.status(200);
res.write(header);
renderToNodeStream(app)
.pipe(
through(
function write(data) {
this.queue(data);
},
function end() {
this.queue(footer);
this.queue(null);
}
)
)
.pipe(res);
Usage in Jest
While testing in using jest, if there is a need to emulate SSR, the following string is required to have the test behave the way they are expected to.
import { HelmetProvider } from 'react-helmet-async';
HelmetProvider.canUseDOM = false;
License
Licensed under the Apache 2.0 License, Copyright © 2018 Scott Taylor