@nuxtjs/markdownitのインストールとセットアップ【Nuxt.js×TypeScript】
  • 2022.02.20に公開
  • ブログ構築TS
  • 9. ブログMarkdown対応
  • No.1 / 4

今回達成すること

ブログのマークダウン記法に対応するため、Nuxtに@nuxtjs/markdownitを導入します。

2022-02-19 19-33-52

作業に入る前にブランチを切っておきます。

% git checkout -b 20220219_add_blog_function_module

@nuxtjs/markdownitとは

@nuxtjs/markdownitとは、マークダウンをHTMLに変換するmarkdown-itを、Nuxt上で扱えるようにしたモジュールです。

Document: nuxt-community/markdownit-module - GitHub

markdown-itはマークダウン記法で書かれたテキストをHTMLにマークアップするモジュールです。

@nuxtjs/markdownitのインストールとセットアップ

それではインストールを行いましょう。

% yarn add @nuxtjs/markdownit

# インストール確認
% yarn list --pattern @nuxtjs/markdownit

├─ @nuxtjs/markdownit-loader@1.2.0
└─ @nuxtjs/markdownit@2.0.0

セットアップを行う

nuxt.config.js@nuxtjs/markdownitのセットアップを行います。

nuxt.config.js
export default {
  ...
  modules: [
    ...
    // 追加
    // https://www.npmjs.com/package/@nuxtjs/markdownit
    '@nuxtjs/markdownit'
  ],
  ...
  // 追加
  // Doc: https://github.com/markdown-it/markdown-it
  markdownit: {
    /*
      preset: markdownのルールの決定
        commonmark: コモンマークモードに設定
        default: 利用可能なすべてのルールが有効になる(html, typographer, autolinkerは含まれない)
        zero: すべてのルールを無効(太字と斜体のマークアップだけが必要で、他は何も必要ない場合などに使用)
      Doc: https://markdown-it.github.io/markdown-it/#MarkdownIt.new
    */
    preset: 'default',
    // ソース内のHTMLタグを有効にする
    html: true,
    // 段落の\nを<br>に変換する
    breaks: true,
    // URLのようなテキストをリンクに変換する
    linkify: false,
    /*
      Nuxt上で$mdを使用できるようにする
      runtime: https://github.com/nuxt-community/markdownit-module#using-md-to-render-markdown
    */
    runtime: true,
    /*
      add plugins
      use: https://markdown-it.github.io/markdown-it/#MarkdownIt.use
    */
    use: []
  },

  // Build Configuration: https://go.nuxtjs.dev/config-build
  build: {
  }
}

runtimeプロパティ

runtimeプロパティにtrueを渡すことで、Vueファイルやtsファイルで$mdが使用できるようになります。

$mdmarkdown-itのクラスインスタンスを呼び出すことができます。

render()を使用することでマークダウンテキストをHTMLにマークアップすることができます。

<div
  v-html="$md.render('# hello')"
/>

オプションのデフォルト値

markdown-itの各プロパティのデフォルト値は以下のようになります。

var md = require('markdown-it')({
  html:         false,        // Enable HTML tags in source
  xhtmlOut:     false,        // Use '/' to close single tags (<br />).
                              // This is only for full CommonMark compatibility.
  breaks:       false,        // Convert '\n' in paragraphs into <br>
  langPrefix:   'language-',  // CSS language prefix for fenced blocks. Can be
                              // useful for external highlighters.
  linkify:      false,        // Autoconvert URL-like text to links
  typographer:  false,
  quotes: '“”‘’',
  highlight: function (/*str, lang*/) { return ''; }
});

引用: markdown-it - GitHub

型定義ファイルをインストールする

matkdown-itの型定義ファイルは別に用意されています。

devDependenciesにインストールするので--devオプションを付けてインストールします。

% yarn add --dev @types/markdown-it

型定義ファイルの登録

型定義ファイルをtsconfig.jsonに登録します。

tsconfig.json
{
  ...
    "types": [
      ...
      // 追加
      "@types/markdown-it"
    ]
  },
  ...
}

Nuxtインスタンスに$mdを登録する

$mdは、Nuxtのデフォルトの型定義では用意されていないので、NuxtコンテキストとVueインスタンスに型登録を行います。

types/module.d.ts
// 一番上に追加
import MarkdownIt from 'markdown-it'

declare module 'vue/types/vue' {
  // Vueインスタンス(this)の型追加
  interface Vue {
    ...
    // 追加
    // @nuxtjs/markdownit
    $md: MarkdownIt
  }
}

declare module '@nuxt/types' {
  // Nuxt Contextへの型追加
  interface Context {
    ...
    // 追加
    // @nuxtjs/markdownit
    $md: MarkdownIt
  }
	...
}

これで$mdthis.$mdを呼び出してもタイプエラーが発生し無くなりました。

// OK
asyncData ({ $md }: Context) {
  console.log($md)
}

// OK
console.log(this.$md)

以上で@nuxtjs/markdownitのセットアップは完了です。

Markdown記事をContentfulに投稿する

ここまでの実装の確認を行うため、Markdownを使用した記事をContentfulに投稿します。

markdown-itのデモページから、マークダウンテキストをコピーします。

markdown-it demo

Contentfulに新しいブログ記事を作成しましょう。

コピーしたテキストをのブログモデルの「body」に貼り付けます。

Contentfulへの記事投稿方法を忘れた方はこちらをご覧ください。

2022-02-19 19-09-15

この記事は今後のスタイリングの参考にするので下書きのままでOKです。

Nuxtに記事の内容を表示する

ブログ記事のコンテンツページにbodyを追加します。

pages/posts/_category/_slug.vue
<template>
  <div>
    Post title: {{ post.fields.title }}
    <!-- 追加 -->
    <div>
      {{ post.fields.body }}
    </div>
  </div>
</template>

作成した記事をブラウザで表示してみましょう。

テキストベースのbodyが表示されます。

2022-02-19 19-17-28

markdown-itでマークアップする

Markdownテキストをマークアップするには$md.render()を使用します。

pages/posts/_category/_slug.vue
<template>
  <div>
    Post title: {{ post.fields.title }}
    <div>
      <!-- 追加 -->
      <div
        v-html="$md.render(post.fields.body)"
      />
      <!-- 削除 -->
      <!-- {{ post.fields.body }} -->
    </div>
  </div>
</template>

v-htmlのESLint警告を非表示にする

v-htmlを使用すると、XSS攻撃のきっかけになるのでESLintの警告が出ます。

terminal
WARNING in pages/posts/_category/_slug.vue
vue/no-v-html: 'v-html' directive can lead to XSS attack.

v-htmlに渡す値が信頼できる値の場合、この警告は無視して構いません。

ESLintの警告を非表示にする設定を行います。

pages/posts/_category/_slug.vue
<template>
  <div>
    Post title: {{ post.fields.title }}
    <div>
      <!-- eslint-disable vue/no-v-html -->
      <div
        v-html="$md.render(post.fields.body)"
      />
    </div>
  </div>
</template>
  • eslint-disable <ルール名> ... そのファイルの特定のルールの警告を無効にする。

    参考: Rules - ESLint

マークアップをブラウザで確認しよう

先程のテキストデータがマークアップされていますね。

ちなみに画像の大きさなどはCSSで調整する必要があります。

2022-02-19 19-33-52

今回の作業は以上です。

% git commit -am "Add @nuxtjs/markdownit module"

まとめと次回

今回はマークダウン記法に対応するために、Nuxtに@nuxtjs/markdownitを導入しました。

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

そこで次回は内部リンクを同じタブで、外部リンクを新規タブで開く実装を行います。

あなたの力になれること
私自身が独学でプログラミングを勉強してきたので、一人で学び続ける苦しみは痛いほど分かります。そこで、当時の私がこんなのあったら良いのにな、と思っていたサービスを立ち上げました。周りに質問できる人がいない、答えの調べ方が分からない、ここを聞きたいだけなのにスクールは高額すぎる。そんな方に向けた単発・短期間メンターサービスを行っています。
独学プログラマのサービス
ブログ構築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制作のご依頼は下記メールアドレスまでお送りください。