Every business craves to be called as the best in their own industry and in the cutting-edge age that we live in, reaching on top proportionally means ranking top on the Google Search.
From development perspective, JavaScript frameworks produce Single-Page Applications, which are gaining moment fast because of their fast development lifecycle. The good thing about Single Page Apps is that they keep the front end and backend, known as presentation and data layer, separate, hence, both the teams can put their efforts simultaneously. It benefits in scaling using a microservice architecture in comparison to any multi-page app.
The good thing about Single Page Apps is that they keep the front end and backend, known as presentation and data layer, separate, hence, both the teams can put their efforts simultaneously. It benefits in scaling using a microservice architecture in comparison to any multi-page app.
Search engines are yet to effectively identify the JavaScript, which means SPAs built on top of Facebook’s React, Google’s own Angular, etc. fail miserably when it comes to crawlers on the search engines.
This prevents a lot of people to use these amazing JavaScript frameworks. Although, Server-side rendering (SSR) solves this problem to an extent, but everything has its limitations, right?
So, we’ve already established the issue, it is indeed a great concern. So, How do I use SEO in React JS? Let’s find out!
React Helmet is a reusable React component that handles the changes in your document’s head. It takes-in and outputs plain HTML tags, this feature alone makes this a perfect addition to your project for making the Search engines and social media love your React App.
This blog post will help you to understand, how you can use React-Helmet in your production projects. It’s a piece of cake to update meta-tags on the server as well as client with React Helmet, this means that this library is an appropriate preference for making your apps not just search engine optimized but also social media friendly.
Getting Started
You can very easily create a react app with the help of yarn or npm commands as below:
npx create-react-app react-helmet-tutorial
cd react-helmet-tutorial
npm start
# OR using Yarn:
yarn create react-app my-app
yarn start
After a while, when all of the required modules and configurations are applied, your app is ready at http://localhost:3000.
React also has a <head> element just like any other Single Page Applications; hit F12 in Chrome or Ctrl+Shift+C in Firefox to witness this yourselves.
Here how a <head> element looks like:
<head>
<meta charset="utf-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#000000">
<meta name="description" content="Web site created using create-react-app">
<link rel="apple-touch-icon" href="/radiant.png">
<link rel="manifest" href="/manifest.json">
<title>React App</title>
<style type="text/css">
<!-- CSS -->
</style>
</head>
Making changes in public/index.html results in the update in <head> but it is not favorable and recommended always.
Installation, Configuration, & Implementation
You can install React Helmet into your project using npm or Yarn:
npm install react-helmet
# OR, using Yarn:
yarn add react-helmet
Importing the Helmet component is the starting point, then you insert the elements you want in your document’s <head>.
// src/App.js
import React from "react";
import "./App.css";
import { Helmet } from "react-helmet";
function App() {
return (
<div className="App">
<Helmet>
<html lang="en" />
<title>React Helmet for SEO</title>
<meta name="description" content="Quick React Helmet Tutorial" />
<meta name="theme-color" content=" #D90907" />
</Helmet>
<header className="App-header">Title is React Helmet for SEO</header>
</div>
);
}
export default App;
When you update the src/App.js file, you will see the title of the React app change.
Here, we are only using the elements names <title>, <html>, and <meta> for title, description and theme-color, but other elements such as base, meta, link, script, noscript, and style as children of Helmet can be extensively used here.
Attributes can also be easily mentioned for the body and html tags. For example:
<Helmet>
{/* html attributes */}
<html lang="en" />
{/* body attributes */}
<body className="dark" />
{/* title element */}
<title>React Helmet for SEO</title>
{/* base element */}
<base target="_blank" href=" http://nexgeniots.com/blogs/" />
{/* meta elements */}
<meta name="description" content="Tutorial for React Helmet" />
<meta name="theme-color" content="#D90907" />
{/* link elements */}
<link rel="canonical" href=" http://nexgeniots.com/blogs/" />
</Helmet>
What is preferred: The Parent or the Child?
We all like babies, hence, preference goes to Child components here as well. Take an example below:
// src/Children.js
import React from "react";
import { Helmet } from "react-helmet";
function Children() {
return (
<div>
<Helmet>
<title>Rile them children up! </title>
</Helmet>
{" "} This time title will be Child Component Rocks!
</div>
);
}
export default Children;
Upon importing the child component (i.e., Children.js) to (i.e., App.js), the meta description and theme-color will remain same but the change we desired was the change in the title, that happened successfully.
// src/App.js
import React from "react";
import "./App.css";
import { Helmet } from "react-helmet";
import Children from "./Children";
function App() {
return (
<div className="App">
<Helmet>
<html lang="en" />
<title>React Helmet for SEO</title>
<meta name="description" content="Quick React Helmet Tutorial" />
<meta name="theme-color" content=" #D90907" />
</Helmet>
<header className="App-header">Title is not going to be React Helmet for SEO</header>
</div>
);
}
export default App;
When two child components are being used, the later one will be given preference. For example, if there are <ElderChild /> and <YoungerChild /> — then the component used later in the App.js file will be given preference.
// src/App.js
import React from "react";
import "./App.css";
import { Helmet } from "react-helmet";
import ElderChild from "./ElderChild";
import YoungerChild from "./YoungerChild";
function App() {
return (
<div className="App">
<Helmet>
<title>React Helmet for SEO</title>
<meta name="description" content="Tutorial for React Helmet" />
<meta name="theme-color" content=" #D90907" />
</Helmet>
<header className="App-header">
Title will not be React Helmet for SEO
<ElderChild />
<YoungerChild />
</header>
</div>
);
}
export default App;
If it is the other way around, it would be set according to <ElderChild />:
<header className="App-header">
Title will not be React Helmet for SEO
<YoungerChild />
<ElderChild />
</header>
Server-Side Rendering x React Helmet
As we have seen previously, React Helmet is awesome contender for server-side-rendered React apps. In our next article, we will show ‘how to setup a basic React SSR app.’
In your server-side code, just when you call renderToString in ReactDOMServer or renderToStaticMarkup, you are going to use Helmet’s renderStatic method.
Here’s a quick excerpt for server-side rendering:
// server/index.js
import React from "react";
import express from "express";
import App from "./src/App";
import { Helmet } from "react-helmet";
import { renderToString } from "react-dom/server";
const app = express();
app.get("/*", (req, res) => {
const app = renderToString(<App />);
const helmet = Helmet.renderStatic();
const html = `
<!DOCTYPE html>
<html ${helmet.htmlAttributes.toString()}>
<head>
${helmet.title.toString()}
${helmet.meta.toString()}
${helmet.link.toString()}
</head>
<body ${helmet.bodyAttributes.toString()}>
<div id="root">
${app}
</div>
</body>
</html>
`;
res.send(html);
});
app.listen(8000);
The renderStatic method from Helmet responds with an instance with all required properties, we can use toString() method to render them wherever we want to.
All the helmet properties have a toString() method, to be used inside the html string.
Another cherry on the top: react-helmet-async
As synchronous as it gets, React Helmet probably not always be the best option for SSR. React helmet creates a lot of issues and errors when you want to use it for asynchronous requests, particularly in streaming chunks.
react-helmet-async is a fork of React Helmet.
In developer’s words,
https://github.com/staylor/react-helmet-async
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.
Installation is as simple as running:
npm i react-helmet-async
Just as we have seen in react-helmet, here you will use HelmetProvider to encapsulate the React tree on both the client-side and the server using react-helmet-async.
// src/App.js
import React from "react";
import "./App.css";
import {Helmet, HelmetProvider } from 'react-helmet-async';
function App() {
return (
<HelmetProvider>
<div className="App">
<Helmet>
<title>React Helmet for SEO</title>
<meta name="description" content="React Helmet for SEO Tutorial" />
<meta name="theme-color" content=" #D90907" />
</Helmet>
<header className="App-header">
Title will be React Helmet for SEO
</header>
</div>
</HelmetProvider>
);
}
export default App;
Using React Helmet with React Router
React Helmet is a boon for React Router. Here, you would have to use React Helmet in every route. See below:
A very simple Home.js:
and a very simple About.js as well:
This plays well for any number of routes you throw at it. An interactive session of this example is here.*
*In case you are not seeing the browser debiggin in stackblitz, you might want to allow cookies for the page.
Wrap-up
So, in this read, we learnt to install and implement React-Helmet, its shortcomings, and resolution according to your use-case. Due to its simple turnaround and quick implementation, you can use in absolutely any current or future projects.
Here is a list of must-read references: