プラグインを使わず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