No matter what technology you use, when you use a method to render page meta-data within the head section of the page, one of the ways to achieve this is to write some code within your page to return this code as JSX and then 'copy and paste' that code everywhere else you need to use it. I'm assuming everyone reading this knows this approach would be a terrible idea. Breaking the rule of DRY - don't repeat yourself via code-duplication is a terrible idea.

As the site grows you might want to add in new properties or make global changes within the head section to all your pages. When we work with React we can use React Helmet to solve some of these issues for us. In this tutorial, you will learn a little about React Helmet, how to install and use it. Sound good, then read on.

React Helmet

When it comes to dealing with MetaData and React you do not have to re-invent the wheel yourself. There's a package you can download from NPM called 'React Helmet' that is widely used within the React community. React Helmet has been used on most of the existing projects that I've worked on; most experienced React developers have an understanding of using it, in my opinion, it makes sense to use it. React Helmet is a fairly straight-forward component.

Installing React Helmet

You can install React Helmet via NPM or YARN:

yarn add react-helmet

After Helmet is installed, you can start to use it within your APP. In the teams I've worked in when we've integrated React Helmet we've tended to wrap it within its own component. If you look at the example snippets form blogs etc.. around React Helmet. most of the Helmet stuff is written within the main app.js file. This approach isn't ideal.

In the project's I've worked in, we tend to create a 'MetaTags' component that wraps all the helmet stuff. An example of how a MetaTag component would look is shown below:

import React from 'react';
import Helmet from 'react-helmet';
import { func, shape, string, object, array } from 'prop-types';

const getDefault = {
    title: "My Website", 
    description: "My Website"
    keywords: "My Website"
    robots:""
    canonicalUrl: http://website.com"
};

export const getPageMetadata = metaData => {
    const { title, description, keywords, robots, canonicalUrl } = props;
    const defaultData = getDefault();
    return {
        title: title || defaultData?.title,
        description: description || defaultData?.description,
        keywords: keywords || defaultData?.keywords,
        robots: canonicalUrl || defaultData?.canonicalUrl,,
        canonicalUrl: canonicalUrl || defaultData?.canonicalUrl,
    };
};

const MetaTags = props => {
    const { metaData } = props;
    const meta = getPageMetadata(metaData);
    return (
        <Helmet>
            <title>{meta.title}</title>
            <meta name="description" content={meta.description} />
            <meta name="keywords" content={meta.keywords} />
            {robots && <meta name="robots" content={meta.robots} />}
            <link rel="canonical" href={meta.canonicalUrl} />
        </Helmet>
    );
};

export default MetaTags;

After you have the component up and running, you can then use it on your pages/containers like so:

import { MetaTags } from 'meta-tags';

export class ExamplePage extends Component {
    constructor() {
        super();
    }

    render() {
        const { metaData } = this.props;

        return (
            <div>
                <MetaTags metaData={metaData} />
            </div>
        );
    }
}

Assuming you get this code working and you run the app, after loading the page, if you opened your browser’s elements inspector, the title and meta elements in the head section should be set. If you pass meta-data into the MetaTags component you should see that. If you don't supply anything then the default values will be used. Using this approach means that your page will always have some meta-data as long as you include the MetaTag component into your page.

Rendering MetaTags On The Server

To get meta-tag to render server-side first you need to call either ReactDOMServer renderToString() or renderToStaticMarkup(). To populate the instance with Helmet data you can then use Helmets, renderStatic(). This code would look similar to this:

import Helmet from 'react-helmet';

class App extends Component {
  render() {

    const html = ReactDOMServer.renderToString(<App />);
    const helmet = Helmet.renderStatic();

    return (
      <div>
        <MetaTags />
      </div>
    );
  }
}