Next.jsでブログ記事の構造化データ(JSON-LD)を生成する

Next.jsでブログ記事の構造化データ(JSON-LD)を生成する
公開日時

ブログのNext.js移行に伴い、構造化データ(JSON-LD)も生成する必要があったので対応した。

実装

  • HeadコンポーネントにてjsonLDを表示できるようにしておく(抜粋)

※ そのまま表示するとjsonがエスケープされてしまうのでdangerouslySetInnerHTMLでrawDataを表示する

// components/Head.tsx
import { default as NextHead } from 'next/head'
import React from 'react'

type Props = {
  title?: string
  jsonLd?: string
}

export const Head = ({ title, jsonLd }: Props) => {
  const defaultTitle = process.env.NEXT_PUBLIC_SITE_NAME

  return (
    <NextHead>
      <title>{title || defaultTitle}</title>
      {jsonLd && (
        <script
          key="json-ld"
          type="application/ld+json"
          dangerouslySetInnerHTML={{ __html: jsonLd }}
        />
      )}
    </NextHead>
  )
}
  • 記事ページでJSON-LDを生成してHeadコンポーネントに渡す(抜粋)
// pages/posts/[slug].tsx
import React from 'react'

const generateJsonLd = (post: BlogPost) => {
  const siteUrl = process.env.NEXT_PUBLIC_SITE_URL
  const path = `/posts/${post.slug}`
  const url = `${siteUrl}${path}`
  const defaultOgp = `${siteUrl}/images/ogp.png`

  const imageUrl = post.coverImage?.url || defaultOgp
  const jsonLd = {
    '@context': 'http://schema.org',
    '@type': 'Article',
    name: post.title,
    headline: post.title,
    datePublished: post.publishDate,
    dateModified: post.publishDate,
    url: url,
    mainEntityOfPage: url,
    image: [imageUrl],
    description: post.description,
    author: {
      '@type': 'Person',
      name: 'hello world',
    },
    publisher: {
      '@type': 'Organization',
      name: process.env.NEXT_PUBLIC_SITE_NAME,
      logo: {
        '@type': 'ImageObject',
        url: defaultOgp,
      },
    },
  }
  return JSON.stringify(jsonLd)
}

type Props = {
  post: BlogPost | null
}

const PostPage = ({ post }: Props) => {
  return (
    <Layout>
      <Container>
        <Header />
          <Head
            title={post.title}
            jsonLd={generateJsonLd(post)}
          />
          <article>
            <PostHeader />
            <PostContent content={post.body} />
          </article>
        )}
      </Container>
    </Layout>
  )
}

export default PostPag

確認方法

以前は「構造化データ テストツール」で確認していたが近々廃止になるらしく、代わりに「 リッチリザルト テスト - Google Search Console」を利用して確認を行った。

参考


Related #next.js