Chapter 20

SEO

ここでは、サイトのSEOのためにheadタグを設定していきます。
Reactではheadタグを管理できるreact-helmetというライブラリがあります。
本書では、このライブラリを用いてSEOを行っていきます。

react-helmetの導入

インストール

$ npm install --save react-helmet

SEOコンポーネントの作成

タイトルと説明を親コンポーネントから受け取り、設定します。
Helmetタグ内に以下のように設定するだけで、headタグに変換されHTMLタグの先頭に追加されます。React(Gatsby)のようにJavaScriptでDOMを生成してページを作る場合においては、headタグへのデータの設定や管理が難しいので、react-helmetは非常に便利です。

// src/components/seo.js
import React from "react"
import { Helmet } from "react-helmet"

const SEO = ({ title, description }) => {
    return (
        <Helmet
            htmlAttributes={{ lang: "ja-jp" }}
            title={title}
            titleTemplate={`%s`}
            meta={[
                {
                    name: `description`,
                    content: description,
                },
                {
                    property: `og:title`,
                    content: title,
                },
                {
                    property: `og:description`,
                    content: description,
                },
                {
                    property: `og:type`,
                    content: `website`,
                },
                {
                    property: `og:site_name`,
                    content: `Dev Blog`,
                },
                {
                    property: `og:locale`,
                    content: `ja_JP`,
                },
            ]}
        />
    )
}

export default SEO

トップページへの設定

トップページからSEOコンポーネントを呼び出します。

// src/pages/index.js
import React from "react"
import Layout from "../components/layout"
import Hero from "../components/hero"
import PostLink from "../components/post-link"
import { graphql } from "gatsby"
import SEO from "../components/seo"

export default function Home({ data }) {
  return (
    <Layout>
      <SEO title="Dev Blog" description="Gatsbyを使って作ったブログです" />
      <Hero />
      {data.allContentfulPost.edges.map(edge =>
        <PostLink key={edge.node.slug} post={edge.node} />
      )}
    </Layout>
  )
}
~省略~

記事詳細ページへの設定

記事詳細ページからSEOコンポーネントを呼び出します。

// src/templates/post.js
import React from "react"
import "../styles/post.css"
import Layout from "../components/layout"
import SEO from "../components/seo"

export default function Post({ pageContext }) {
    const { title, updatedAt, image } = pageContext.post;
    const description = pageContext.post.description.description;
    const body = pageContext.post.body.childMarkdownRemark.html;

    return (
        <Layout>
            <SEO title={title} description={description} />
            <div className="post-header">
                <h1>{title}</h1>
                <p className="post-date">{updatedAt}</p>
            </div>
            <img src={image.file.url} className="post-image" alt="post-cover"></img>
            <div dangerouslySetInnerHTML={{ __html: body }} className="post-body" />
        </Layout>
    )
}

設定後、ページを開きページのHTMLを確認すると設定した内容がheadタグ内に記載されています。