Nuxt.js×markdown-it 外部リンクを別タブで開くプラグインを追加しよう
  • 2022.02.20に公開
  • ブログ構築TS
  • 9. ブログMarkdown対応
  • No.2 / 4

今回達成すること

markdown-itのデフォルトの挙動は、外部リンクを新規タブで開きません。

そこでmarkdown-itに外部リンクを新規タブで開く、markdown-it-link-attributesプラグインを追加します。

2022-02-20 13-00-23

Contentfulの記事に内部リンクを追加する

事前にContentfulのマークダウン記事に内部リンクを用意しましょう。

パスはご自身の内部リンクに書き換えてください。

[内部リンクが別タブで開かないかテスト](/posts/main-category-01/demo-blog-10)

2022-02-20 12-51-21

Nuxtに記事へのリンクを用意する

Nuxtのトップページにマークダウン記事リンクを設置します。

pagea/index.vue
<template>
  <div>
    <v-container>
      <!-- 追加 -->
      <v-card-title
        class="font-weight-bold"
      >
        <nuxt-link
          to="/posts/main-category-01/markdown-test"
        >
          @nuxtjs/markdownit test
        </nuxt-link>
      </v-card-title>
      ...
</template>

マークダウン記事に遷移するリンクが用意できました。

2022-02-20 12-55-39

リンクを操作するプラグインを追加する

リンクを操作するmarkdown-itのプラグインはmarkdown-it-link-attributesを使用します。

下記コマンドでインストールします。

% yarn add markdown-it-link-attributes

markdown-itへプラグインを追加する方法

markdown-itへのプラグインの追加とセットアップはnuxt.config.jsで行います。

markdown.useプロパティ内に配列を追加し、

  • 1つ目の値にプラグイン名
  • 2つ目の値にプラグインのオプション

を渡すことで追加とセットアップを行います。

nuxt.config.js
markdown: {
  use: [
    [
      'プラグイン名',
      { 'オプション': ... }
    ]
  ]
}

markdown-it-link-attributesのセットアップを行います。

useプロパティに以下を追加してください。

nuxt.config.js
markdownit: {
  ...
  use: [
    /*
      <a>タグの操作
      Doc: https://github.com/crookedneighbor/markdown-it-link-attributes
    */
    ['markdown-it-link-attributes', {
      // matcher: trueを返すリンクにattrsオプションを付与する
      matcher (href, _config) {
        // '/'から始まらないリンク(外部リンク)にtrueを返す
        return /^(?!\/)/.test(href)
      },
      attrs: {
        // markdownリンクにclassを付与する
        // class: 'my-class',
        target: '_blank',
        rel: 'noreferrer'
      }
    }]
  ]
},

matcher()trueを返した場合、attrsで指定したプロパティが<a>タグに付与されます。

  • matcher()

    • 第一引数 href ... <a>タグのhrefプロパティの値が返る。

    • 第二引数 config ... オプションオブジェクトが格納されている。

configの実態はこんな感じです。

config {
  matcher: [Function: matcher],
  attrs: {
    target: '_blank',
    rel: 'noreferrer'
  }
}

/^(?!/)/.test(href)の意味

外部リンクのhrefの値は必ずhttpから始まり、内部リンクは/で始まります。

正規表現の否定的先読みを使用し、外部リンクの場合にtrueを返しています。

否定的先読みとは

?! で始まる正規表現を括弧 () で括ることにより、指定した文字列を含まないという条件(否定的先読み)でマッチングを行うことができます。

引用: 正規表現で文字列を含まない、否定の記述 | UX MILK

今回のコードは以下の意味を持ちます。

  • /^(?!\/)/.test(href)
    • ^ ... 先頭の文字列が
    • (?!\/) ... /から始まらない
    • test(href) ... hrefの値にtrueを返す

matcher内でログをとると、ターミナルに以下のログが出力されます。

// nuxt.config.js
matcher (href, _config) {
  console.log(href, /^(?!\/)/.test(href))
}

// terminal
/posts/main-category-01/demo-blog-10 false
https://nodeca.github.io/pica/demo/ true
https://github.com/nodeca/babelfish/ true
http://dev.nodeca.com true
http://nodeca.github.io/pica/demo/ true
https://www.npmjs.org/browse/keyword/markdown-it-plugin true
https://github.com/markdown-it/markdown-it-emoji true
...

これで外部リンクを別タブで開く設定は完了です。

ブラウザでaタグを確認しよう

マークダウン記事に移動して、外部リンクにのみtargetrefプロパティが付与されているか確認してください。

対して内部リンクにはプロパティが追加されていません。

2022-02-20 13-00-23

今回の作業は以上です。

% git commit -am "Add markdown-it link-attributes plugin"

まとめと次回

今回は外部リンクを新規タブで開くために、markdown-itにプラグインを追加しました。

現状、内部リンクの<a>タグはページがリロードされます。

次回はこの挙動を<nuxt-link>と同じ挙動にし、高速にページ遷移を行う実装を行います。

あなたの力になれること
私自身が独学でプログラミングを勉強してきたので、一人で学び続ける苦しみは痛いほど分かります。そこで、当時の私がこんなのあったら良いのにな、と思っていたサービスを立ち上げました。周りに質問できる人がいない、答えの調べ方が分からない、ここを聞きたいだけなのにスクールは高額すぎる。そんな方に向けた単発・短期間メンターサービスを行っています。
独学プログラマのサービス
ブログ構築TSの投稿
1
  • Nuxt.js×TypeScript開発環境構築
  • /
  • #01
Nuxt.jsをローカルPCに立ち上げよう
2
  • Nuxt.js×TypeScript開発環境構築
  • /
  • #02
Nuxt.jsプロジェクトをGitHubにPushしよう
3
  • Nuxt.js×TypeScript開発環境構築
  • /
  • #03
nuxt-property-decoratorのインストールとTypeScriptのセットアップ
1
  • Vuetifyセットアップ
  • /
  • #01
TypeScript環境のNuxt.jsにVuetifyを導入しよう
2
  • Vuetifyセットアップ
  • /
  • #02
VuetifyにカスタムCSSを追加してSASS変数を理解しよう
3
  • Vuetifyセットアップ
  • /
  • #03
VuetifyにカスタムSVGアイコンを追加しよう
1
  • NetlifyCLIを使ったNuxtデプロイ
  • /
  • #01
Netlify CLIをインストールして本番環境のサイトを作成しよう
2
  • NetlifyCLIを使ったNuxtデプロイ
  • /
  • #02
netlify.tomlを使ってNuxt.jsをNetlifyに手動デプロイしよう
1
  • Contentfulモデル構築
  • /
  • #01
Contentfulの料金とCommunityプランの無料枠を理解する
2
  • Contentfulモデル構築
  • /
  • #02
Contentfulへ新規会員登録、ロケールの変更、API Keyの発行を行う
3
  • Contentfulモデル構築
  • /
  • #03
Contentful ブログカテゴリーモデルを作成しよう
4
  • Contentfulモデル構築
  • /
  • #04
Contentful カテゴリーモデルに1対1で関連づくblogPostモデルを作成しよう
5
  • Contentfulモデル構築
  • /
  • #05
Contentful ブログ記事に1対多で関連づくplogTagモデルを作成しよう
6
  • Contentfulモデル構築
  • /
  • #06
Contentful カテゴリー・ブログ記事・タグコンテンツを作成しよう
1
  • Nuxt.js×Contentfulセットアップ
  • /
  • #01
Nuxt.js×Contentfulセットアップ。モジュールのインストールからAPI Keyの登録まで
2
  • Nuxt.js×Contentfulセットアップ
  • /
  • #02
Contentful APIリクエストの実行 Nuxt.jsにブログコンテンツを表示しよう
3
  • Nuxt.js×Contentfulセットアップ
  • /
  • #03
ContentfulAPIをNetlifyにデプロイしよう【Nuxt FullStaticのasyncDataとfetch】
1
  • Vuex×TypeScriptセットアップ
  • /
  • #01
Vuexの型付け vuex-module-decoratorsとnuxt-typed-vuexどちらを使用するか
2
  • Vuex×TypeScriptセットアップ
  • /
  • #02
nuxt-typed-vuexのインストールとセットアップ。Vuexの型定義と呼び出し方
3
  • Vuex×TypeScriptセットアップ
  • /
  • #03
VuexにContentfulの型定義ファイルとnuxtServerInitを追加しよう
4
  • Vuex×TypeScriptセットアップ
  • /
  • #04
VuexにContentfulAPIレスポンスを保存してVueファイルに表示しよう
1
  • コンテンツページ構築
  • /
  • #01
ブログアプリのページ設計とNuxt.jsの動的ルーティングについて理解しよう
2
  • コンテンツページ構築
  • /
  • #02
カテゴリーのコンテンツページを作成しよう【Nuxt.js×Contentful】
3
  • コンテンツページ構築
  • /
  • #03
カテゴリーに関連付くブログ記事一覧を表示しよう【Nuxt.js×Contentful】
4
  • コンテンツページ構築
  • /
  • #04
injectを使用して共通エラー処理メソッドを作成しよう【Nuxt×TypeScript】
5
  • コンテンツページ構築
  • /
  • #05
NuxtChildを使用してブログ記事ページを作成しよう【Nuxt.js×TypeScript】
6
  • コンテンツページ構築
  • /
  • #06
タグ一覧ページとタグ関連づく記事一覧を表示しよう【Nuxt.js×TypeScript】
7
  • コンテンツページ構築
  • /
  • #07
プライバシーポリシーページを作成しよう【Nuxt.js×TypeScript】
8
  • コンテンツページ構築
  • /
  • #08
@nuxtjs/i18nのインストールとセットアップ。ページタイトルの翻訳化【TypeScript】
1
  • NetlifyFunctionsを使った検索機能
  • /
  • #01
Netlify Functionsを使ってクエリを返す関数を作成しよう【Nuxt.js×TypeScript】
2
  • NetlifyFunctionsを使った検索機能
  • /
  • #02
Netlify Functionsプロジェクトをデプロイしよう【Nuxt.js×TypeScript】
3
  • NetlifyFunctionsを使った検索機能
  • /
  • #03
Nuxt.js × axiosセットアップ Netlify Functionsにリクエストを行う準備をしよう
4
  • NetlifyFunctionsを使った検索機能
  • /
  • #04
オリジン•CORS•プリフライトリクエストを理解する【Nuxt.js×Netlify Functions】
5
  • NetlifyFunctionsを使った検索機能
  • /
  • #05
Netlify Functionsを使ってフォームバリデーション機能を構築しよう【Nuxt.js】
6
  • NetlifyFunctionsを使った検索機能
  • /
  • #06
ツールバーに表示する検索フォームを作成しよう【Nuxt.js×TypeScript】
7
  • NetlifyFunctionsを使った検索機能
  • /
  • #07
検索ページを作成しよう【Vue propsとTypeScriptの書き方 解説】
8
  • NetlifyFunctionsを使った検索機能
  • /
  • #08
Netlify FunctionsからContentfulAPIリクエストを送ろう【Nuxt.js】
9
  • NetlifyFunctionsを使った検索機能
  • /
  • #09
検索ページに「もっと見る」ボタンを実装しよう【Nuxt.js×TypeScript】
1
  • ブログMarkdown対応
  • /
  • #01
@nuxtjs/markdownitのインストールとセットアップ【Nuxt.js×TypeScript】
2
  • ブログMarkdown対応
  • /
  • #02
Nuxt.js×markdown-it 外部リンクを別タブで開くプラグインを追加しよう
3
  • ブログMarkdown対応
  • /
  • #03
Nuxt.js×markdown-it 内部リンクをVueRouterで高速にページ遷移しよう
4
  • ブログMarkdown対応
  • /
  • #04
Nuxt.js×markdown-it アンカーリンクとブログ目次を自動生成しよう
独学プログラマ
独学でも、ここまでできるってよ。
CONTACT
Nuxt.js制作のご依頼は下記メールアドレスまでお送りください。