Nuxt Content × SSG で作る静的ブログ。1:概念とセットアップ
技術スタック JavascriptNuxt.js

Nuxt Content × SSG で作る静的ブログ。1:概念とセットアップ

2021.05.09 2021.05.04

こんにちはjunです。私のブログは2021年4月にwordpressを卒業し、Nuxt contentというものを使用してリニューアルしました。wordpressは簡単にサイトは作れますし使い勝手はいいですが、公開サーバーにCMSがあるためにセキュリティ的に問題だったり、大量に記事があるとパフォーマンスが落ちるということがあります。webデベロッパーならばNuxt.jsと静的書き出しぐらいやろうぜ!と思ったのも理由です。

このブログリニューアルにはデータ移行含めて2週間ほどかかりましたが、その途中で少し詰まったり工夫したりした箇所が結構あったのでシリーズ記事として、 「Nuxt Contentによる静的書き出しブログの作成方法」 として書きたいと思います。シリーズを通して以下のことを解説しようと思います。(まだ予定です。もしかすると執筆途中で変わります。)

  1. Nuxt Content の仕組みと基本的な使い方
  2. 記事のレンダリングと静的書き出しルーティング
  3. 記事一覧ページとページング実装
  4. カテゴリーとタグ機能
  5. 記事の管理とデプロイ。SEO対策。アドセンスとアナリティクス設定

それでは一回目は早速、インストールから概念・基本的な使い方について説明していきます。Nuxt.jsにおける構成などは共有しますが、このサイトにおけるデザインの実装方法などは省略しますのでご了承ください。

Nuxt Contentとは?

nuxt contentはNuxt.jsのモジュールです。content/ディレクトリ配下にmarkdownを用いて記事原稿を作成し、Nuxt.jsがmarkdownを解析してオブジェクトとして利用できるようにしてくれます。

$contentというインスタンスがグローバルに使用できますので、それらを利用してコンポーネントにレンダーするという仕組みです。

ブログを構成するソースが全てファイルで構成されるので、GitベースのCMSとして利用することができます。(記事の保存にDBを必要としない。)

自分のブログの構成について

今回のシリーズ記事では私の記事と同じ構成を作成できるように解説していこうと思います。2021年5月現在では以下のような構成・機能を持っています。

  • 記事詳細ページ
  • タグ・カテゴリー
  • 各々の一覧ページとページング
  • シリーズ記事
  • 静的書き出しとデプロイ

詳細に解説します。

記事詳細ページ

私のサイトでは/articles/{sulg}/series/{sulg}/{index}というルートにて各記事本体を見ることができ、そのようなルールで構成されています。スラグ(sulg)は原稿マークダウンのファイル名と一致します。ソースではcontent/ディレクトリ配下にマークダウンファイルを以下のように格納しています。

Nuxt
├── content
│   ├── articles
│   │   ├── aaaaaa.md
│   │   ├── bbbbbb.md
│   │
│   └── series
│       ├── ~~~~~.md
│       ├── ~~~~~.md

上記のように格納することでコンポーネントで、例えばthis.$content('articles')として呼び出すことでarticles配下のデータを取得できます。ファイル名=スラグ名としているので、/articles/aaaaaaaとすることで、aaaaaa.mdの内容がレンダーされるようにしています。このへんのルーティング設定はpage/ディレクトリの構成で制御しています。第二回目で解説します。

タグ・カテゴリー

各記事ではタグとカテゴリーを指定できるようになっています。カテゴリー、タグをクリックするとその一覧に飛ぶのでユーザーはサイトのコンテンツを探しやすくなります。

タグとカテゴリーは実はマークダウンファイルに記述されています。例えばこの記事のマークダウンには一番最初に以下のようなyml形式の記述があります。

---
title: Nuxt Content × SSG で作る静的ブログ。1:概念とセットアップ
description: Nuxt Content × SSG で作る静的ブログ。概念とセットアップについてまずは解説
category: [devstack]
tag: [js,nuxt]
series: nuxt-content-blog
seriesTitle: Nuxt Content × SSG で作る静的ブログ。
index: 1
publish: false
---

上記のカラムは自由につけることができます。例えばseriseindexpublishは私が独自につけています。一方でtitleupdateAtcreatedAtなど自動的に付与される属性もあります。tag, categoryは配列形式の記述をすることでjs側でも配列で扱うことができます。taxonomy.jsというファイルでキーとカテゴリー名、タグを管理しています。(storeでもOKですが、ちょっと困ることがありました。こちらも後で解説します。)

各々の一覧ページとページング

  • /articles/
  • /series/{sulg}/
  • /category/{category_key}/
  • /tag/{tag_key}/

というパスではその記事種別、カテゴリーの一覧が表示されます。1ページあたり15記事表示されるので記事が多くなるとページングが発生します。ページングの際は

  • /articles/page/{n}
  • /series/{sulg}/page/{n}
  • /category/{category_key}/page/{n}
  • /tag/{tag_key}/page/{n}

というルーティングで現在ページを判別しています。ちなみに静的書き出しするときはページごとにディレクトリが作成されます。

静的書き出しとデプロイ

私の場合、まずNuxt.jsには静的書き出し(SSG:static site generate)を使用して作成してページ分のHTMLを生成します。そして生成されたHTMLと画像をrsyncで公開サーバーに送っています。作成全体の流れを簡単に説明しますと、

  1. markdownで原稿を記述
  2. pageコンポーネントに原稿内容をレンダーする。
  3. 公開してよい原稿のみをクエリで取得してルーティングを設定する。
  4. npm run generate を使用して作成した原稿分のHTMLを生成する
  5. rsyncを使用して/dist配下を公開サーバーを同期する

上記のような感じです。結構簡単です。

以上が簡単な概念と構成の説明です。それでは以降からは具体的なインストールと使い方を説明していきます。

インストール方法とセットアップ

Nuxt contentはNuxt.jsのモジュールですのでまずはNuxtプロジェクトを作成します。

npx create-nuxt-app <project-name>

... #普通にNuxtのインストールをする

npm install @nuxt/content

各種の使用バージョンは以下の通りです。
  • Node.js:v12.19.0
  • Nuxt.js:2.14.12
  • Nuxt Content:1.14.0

インストールが終わったので、nuxt.config.jsmodulesに以下のように追記します。

nuxt.config.js
  ...

  modules: [
    '@nuxt/content',
  ],

  ...

そしてcontent/というディレクトリをプロジェクトルートに作成します。

.
├── README.md
├── assets
├── components
├── content # これをつくる
├── layouts
├── middleware
├── node_modules
├── nuxt.config.js
├── package-lock.json
├── package.json
├── pages
├── plugins
├── static
├── store

マークダウンファイルはcontent/配下に作成していくと、nuxt contentは自動的にそれらのファイルを解析してくれます。

そしてcontent/ディレクトリを作成したらさらにarticles/といったディレクトリを作っておくと良いです。別にarticlesとしなくてもいいですが、サブディレクトリ を作ることで$content('articles')のように区別してコンテンツを取得できます。私の場合はarticles/series/というサブディレクトリでコンテンツを区切っています。

記事を試しに作成してみる

マークダウン原稿を作成する

それではarticles/を作ったら何かマークダウンを作成してみましょう。

articles/test.md
---
title: テスト
description:テスト
---
ここに記事内容をマークダウン で記述します。

## 見出し
- リスト
- リスト
- リスト

まずnuxt contentでマークダウン原稿を作る際には、1・2行目に示されたように---で囲ったymlにて書かれたメタデータを記述します。メタデータをかけたら、マークダウン 形式で内容を記述していきます。

ページコンポーネントで読み込む

サンプルを作成したらpage/ディレクトリでページコンポーネントを作成します。今回は簡単に以下のような構成にしてみます。

pages/test.vue
<template>
    <div>
        {{content}}
    </div>
</template>
<script>
export default{
    name:'test_page',
    async asyncData({ store,$content, params }) {
        const content = await $content('articles').fetch();

        return {
            content,
        }
    },
}
</script>

画面は以下のように映ると思います。(私の場合はたくさん記事があるので、たくさんあります。)

変数contentには$content('articles').fetch()によって取得されたページのデータがオブジェクト形式で入っています。

$content('articles').fetch()ではaticles配下のデータが配列でくるので、$content('articles/test').fetch()としてみると単体の該当するファイルが提供されます。

{{content}}ではただのオブジェクトしか表示されません。公式サイトのように <nuxt-content :document="content" />というコンポーネントのdocumentプロップスに$content()で取得したものを渡すことで、HTMLでレンダーされます。

以上でセットアップ完了

以上がNuxt Contentのセットアップと基本的な使い方です。ひとまずモジュールをインストールして$content()を用いて対応するコンテンツを取得することで、ブログを作成できます。

次回は個別記事のレンダリングと$content()の詳細と静的書き出しを行っていこうと思います。

Copyright © 2021 jun. All rights reserved.