プラグインを使わずGatsby(GatsbyJS)で外部リンクは別タブで開くように対応

Webサイト高速化のための 静的サイトジェネレーター活用入門を通じて作成したこのブログは、内部/外部かかわらずリンクは同ページ遷移となっていました。
外部リンクは別タブで開かせたいので調べてはみるものの、コードのハイライト表示に対応した際と同じように、Contentfulのリッチテキストで入力しているため「gatsby-remark-external-links」を使用する方法では対応不可のようです。
参考サイトの情報を元に改修してみたところ、プラグインを使わず対応できたので、ご紹介します。

blogpost-template.jsの編集

INLINESを使えるように定義します。

// 変更前
import { BLOCKS, MARKS } from "@contentful/rich-text-types"

// 変更後
import { BLOCKS, MARKS, INLINES } from "@contentful/rich-text-types"

すでにMARKSの記述がありますが、これはコードのハイライト表示に対応した際、追記したものです。

optionsの[BLOCKS.EMBEDDED_ASSET]...の次あたりに、[INLINES.HYPERLINK]...を追記します。

// 変更前
  renderNode: {
    ...
    ...
    [BLOCKS.EMBEDDED_ASSET]: node => (
      <Img
        fluid={useContentfulImage(node.data.target.fields.file["ja-JP"].url)}
        alt={
          node.data.target.fields.description
            ? node.data.target.fields.description["ja-JP"]
            : node.data.target.fields.title["ja-JP"]
        }
      />
    )

// 変更後
  renderNode: {
    ...
    ...
    [BLOCKS.EMBEDDED_ASSET]: node => (
      <Img
        fluid={useContentfulImage(node.data.target.fields.file["ja-JP"].url)}
        alt={
          node.data.target.fields.description
            ? node.data.target.fields.description["ja-JP"]
            : node.data.target.fields.title["ja-JP"]
        }
      />
    ),
    [INLINES.HYPERLINK]: (node, children) => {
      if (
        // ルート相対用
        node.data.uri.startsWith('/') ||
        // 本番用
        node.data.uri.startsWith('https://frontsensei.com')
      ) {
        // 内部リンク
        return <Link to={node.data.uri}>{children}</Link>;
      }
      // 外部リンク
      return <a href={node.data.uri} target="_blank" rel="noopener noreferrer">{children}</a>;
    },

内部リンクはルート相対で記述するよう運用していれば、「/」の指定でローカルでも本番でも対応が可能です。

念のために、本番用にプロトコルを含めたドメインを判定し、絶対パスで記述されたリンクは内部リンクとするようにしました。

Contentfulから取得した記事にのみ対応しているので、フッターや固定ページにおいては、静的なリンク記述での対応が必要です。

参考サイト

▼Add a target="_blank" to hyperlink within Rich Text Content Type - Authors & Editors - Contentful Community
https://www.contentfulcommunity.com/t/add-a-target-blank-to-hyperlink-within-rich-text-content-type/2650