react-helmet-async vs react-helmet vs react-document-title
React Document Head Management Libraries Comparison
1 Year
react-helmet-asyncreact-helmetreact-document-titleSimilar Packages:
What's React Document Head Management Libraries?

These libraries are designed to manage the document head in React applications, allowing developers to dynamically set the title, meta tags, and other head elements based on the current state of the application. This is crucial for SEO, social sharing, and improving the overall user experience by providing relevant information in the browser tab and search engine results. They help ensure that each page of a single-page application (SPA) has the appropriate metadata, which is essential for both user engagement and search engine optimization.

Package Weekly Downloads Trend
Github Stars Ranking
Stat Detail
Package
Downloads
Stars
Size
Issues
Publish
License
react-helmet-async2,884,9032,22486.3 kB78a year agoApache-2.0
react-helmet2,395,96517,479-2235 years agoMIT
react-document-title72,6801,863-218 years agoMIT
Feature Comparison: react-helmet-async vs react-helmet vs react-document-title

Head Management

  • react-helmet-async:

    react-helmet-async builds on the capabilities of react-helmet by adding support for asynchronous updates. This is particularly useful in scenarios where head management needs to be performed during server-side rendering, ensuring that the correct head elements are sent to the client.

  • react-helmet:

    react-helmet offers a more extensive API for managing not just the title but also meta tags, link tags, and script tags. This allows developers to customize the document head comprehensively, making it suitable for complex applications that require detailed SEO management.

  • react-document-title:

    react-document-title provides a simple API to manage the document title. It allows you to set the title of the document based on the current component's state, making it easy to ensure that the title reflects the content being displayed.

Server-Side Rendering Support

  • react-helmet-async:

    react-helmet-async is specifically designed for server-side rendering and handles asynchronous updates seamlessly, making it the best choice for applications that require SSR and optimal SEO.

  • react-helmet:

    react-helmet can be used with server-side rendering, but it does not handle asynchronous updates effectively, which can lead to issues in SSR scenarios.

  • react-document-title:

    react-document-title does not support server-side rendering, making it less suitable for applications that require SEO optimization through SSR.

Performance

  • react-helmet-async:

    react-helmet-async is optimized for performance in SSR scenarios, allowing for efficient head management without blocking rendering, which can enhance the overall performance of the application.

  • react-helmet:

    react-helmet can introduce some performance overhead due to its comprehensive feature set, but it is generally efficient for most applications. Care should be taken to manage updates properly to avoid unnecessary re-renders.

  • react-document-title:

    react-document-title is lightweight and has minimal performance overhead, making it ideal for applications that only need to manage the document title without additional features.

Ease of Use

  • react-helmet-async:

    react-helmet-async retains the ease of use of react-helmet while adding asynchronous capabilities, making it accessible for developers familiar with react-helmet.

  • react-helmet:

    react-helmet has a steeper learning curve due to its extensive features, but it provides powerful capabilities for those who need detailed control over the document head.

  • react-document-title:

    react-document-title is straightforward and easy to use, making it an excellent choice for developers who need a quick solution for managing document titles without complexity.

Community and Support

  • react-helmet-async:

    react-helmet-async, while newer, is gaining traction and benefits from the existing react-helmet community, providing a growing base of support and resources.

  • react-helmet:

    react-helmet has a larger community and extensive documentation, providing ample resources for troubleshooting and implementation.

  • react-document-title:

    react-document-title has a smaller community and fewer resources compared to the other libraries, which may limit support options.

How to Choose: react-helmet-async vs react-helmet vs react-document-title
  • react-helmet-async:

    Choose react-helmet-async if you need server-side rendering (SSR) support and want to manage head elements asynchronously. This package is particularly beneficial for applications that require improved performance and SEO capabilities when rendering on the server, as it allows for better handling of head updates during asynchronous operations.

  • react-helmet:

    Choose react-helmet if you require a more comprehensive solution for managing the document head, including meta tags, links, and scripts. It offers a rich API and is suitable for applications that need detailed control over the head elements, especially for SEO and social media sharing.

  • react-document-title:

    Choose react-document-title if you need a simple solution for managing the document title in a straightforward manner without additional overhead. It is lightweight and focuses solely on the document title, making it ideal for smaller projects or when you don't need extensive head management features.

README for react-helmet-async

react-helmet-async

CircleCI

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;

// helmet.title.toString() etc…

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;

Prioritizing tags for SEO

It is understood that in some cases for SEO, certain tags should appear earlier in the HEAD. Using the prioritizeSeoTags flag on any <Helmet> component allows the server render of react-helmet-async to expose a method for prioritizing relevant SEO tags.

In the component:

<Helmet prioritizeSeoTags>
  <title>A fancy webpage</title>
  <link rel="notImportant" href="https://www.chipotle.com" />
  <meta name="whatever" value="notImportant" />
  <link rel="canonical" href="https://www.tacobell.com" />
  <meta property="og:title" content="A very important title"/>
</Helmet>

In your server template:

<html>
  <head>
    ${helmet.title.toString()}
    ${helmet.priority.toString()}
    ${helmet.meta.toString()}
    ${helmet.link.toString()}
    ${helmet.script.toString()}
  </head>
  ...
</html>

Will result in:

<html>
  <head>
    <title>A fancy webpage</title>
    <meta property="og:title" content="A very important title"/>
    <link rel="canonical" href="https://www.tacobell.com" />
    <meta name="whatever" value="notImportant" />
    <link rel="notImportant" href="https://www.chipotle.com" />
  </head>
  ...
</html>

A list of prioritized tags and attributes can be found in constants.ts.

Usage without Context

You can optionally use <Helmet> outside a context by manually creating a stateful HelmetData instance, and passing that stateful object to each <Helmet> instance:

import React from 'react';
import { renderToString } from 'react-dom/server';
import { Helmet, HelmetProvider, HelmetData } from 'react-helmet-async';

const helmetData = new HelmetData({});

const app = (
    <App>
      <Helmet helmetData={helmetData}>
        <title>Hello World</title>
        <link rel="canonical" href="https://www.tacobell.com/" />
      </Helmet>
      <h1>Hello World</h1>
    </App>
);

const html = renderToString(app);

const { helmet } = helmetData.context;

License

Licensed under the Apache 2.0 License, Copyright © 2018 Scott Taylor