BETA

@nuxt/contentでブログを構築してみました

投稿日:2020-05-29
最終更新:2020-06-05

これまで nuxt と microCMS を組み合わせて JAMStack なブログを Netlify で公開していましたが、コンテンツ自体も一緒に管理できたほうが効率的かつ外部サービスに依存したくないと考え、作り直しのため markdown-it を採用つもりでした。

しかし@nuxt/content が公開されたことを知り、早速導入をしてみました。

@nuxt/content の機能について

  • ホットリロード
  • Markdown の Vue コンポーネント
  • 全文検索
  • nuxt generateで静的サイトの生成
  • MongoDB のような QueryBuilder
  • PrismJS によるマークダウンファイルのコードブロックをスタイリングする
  • 目次の生成
  • Markdown、CSV、YAML、JSON を処理する
  • hooks による拡張
  • types による Typescript のサポート (v1.0.1)

インストール時の環境

  • MacOS Catalina 10.15.4
  • yarn 1.22.4
  • NuxtJS 2.12.2 (TypeScript)
  • @nuxt/content v1.2.0

インストール

まずはパッケージをインストールします。

yarn add @nuxt/content

次に nuxt.config.ts に以下を追加します。

# nuxt.config.ts  
{  
  modules: [  
      '@nuxt/content',  
  ],  
  content: {  
    // デフォルト以外の設定  
  }  
}  

TypeScript の対応

tsconfig.jsonに以下を追加します。

{  
  "compilerOptions": {  
    "types": ["@nuxt/types", "@nuxt/content"]  
  }  
}  

これを追加することで Context を拡張して、後に出てくる$contentの参照が行われるようにします。

コンテンツの管理

コンテンツの管理はデフォルトでは~/content以下で行います。

それぞれのファイルはサブディレクトリでも管理することができます。

今回は~/content/articles/sample.mdとして作成してみます。

---  
title: '日本語タイトルを使えます'  
date: 2020-05-23  
tags: [Markdown, NuxtJS]  
---  

# 記事タイトル  

コンテンツの内容  

@nuxt/contentで slug は、ファイル名の拡張子を除く部分となっています。

YAML Front Matte の機能として記事のメタデータを管理することができ、tagsのように配列で記述できます。

これらのメタデータはクエリを使って絞り込みに利用できます。

注意点としてtitletitle: 1のように文字列以外を入力すると、文字列の関数がないことでエラーが発生します。この場合はシングルクォートで括るようにすれば回避できます。

コンテンツの表示

asyncDataを使ってサーバーサイドで記事を取得します。

<template>  
  <div>  
    <div>{{ page.title }}</div>  
    <div>{{ page.date }}</div>  
    <nuxt-content :document="page" />  
  </div>  
</template>  

<script lang="ts">  
import { Vue, Component } from 'nuxt-property-decorator'  
import { Context } from '@nuxt/types'  

@Component  
export default class Sample extends Vue {  
  async asyncData({ $content, params, error }: Context) {  
    const page = await $content('articles/sample').fetch()  
    return { page }  
  }  
}  
</script>  

$content('articles/sample')とすると、content/articles/sampleを記事として取得します。

複数の記事をまとめて取得するには$content('articles')として、content/articles以下にある全ての記事を配列で取得することができます。

サーバーサイドで取得後、page変数には記事ファイルのメタデータとコンテンツが読み込まれ、
<nuxt-content :document="page">で HTML にマークアップされた状態で表示されます。

コードブロックのテーマを変更する

@nuxt/contentでコードブロックのハイライトはprismjsで行われているので、prism-themesをインストールすれば好きなテーマへ変更することができます。

yarn add prism-themes  

nuxt.config.ts でテーマの変更を設定します。

# nuxt.config.ts  
{  
  modules: [  
      '@nuxt/content',  
  ],  
  content: {  
    markdown: {  
      prism: {  
        // ここに使いたいcssのテーマを設定します  
        theme: 'prism-themes/themes/prism-vsc-dark-plus.css'  
      }  
    }  
  }  
}  

タグの検索をする

メタデータが配列の場合は、単純な where では取得できません。

@nuxt/contentのクエリはLokiJSを使っているので、公式マニュアルを参照して$containsを使えばいいことがわかりました。

具体的には以下の方法で、特定のタグを持つ記事を取得することができます。

await $content('articles')  
  .where({ tags: { $contains: 'Markdown' } })  
  .fetch()  

サブディレクトリの記事も取得するには

v1.3.0で実装されました。TypeScriptを使っている場合は$contentの引数に問題があるので、v1.3.1を使いましょう。

これでフラットな記事管理から解放されます。

const articles = $content('articles', { deep: true })  

終わりに

開発速度が速く、どんどん機能追加がされていて、シンプルで使いやすい印象です。

実際に導入までの作業も簡単で、公式ドキュメントを見ながら行うことができました。

目的としていた記事の一元管理を短時間で構築することができました。今後ますます注目されそうな気がします。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

naozoの技術ブログ 主にFlutterに関する記事を上げています

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう