yourmystar tech blog
著者: fulu 公開日:

Nuxt Content V2 はいいぞ

この記事はユアマイスター アドベントカレンダー 2022の 1 日目の記事です。

はじめに

10/16(日)に日本最大の Vue.js カンファレンスであるVue Fes Japan Online 2022が開催されました。ここで Nuxt Content について LT をしてきたので、その内容を記事でも紹介させていただきます。

ブログ開発に対するモチベーション

すでに様々なブログのサービスが存在していますが、一から開発したいニーズは一定数あると考えています。理由の一つとしてデザインやキャッシュ戦略など自分好みにカスタマイズしたいというニーズがあると思います。 カスタマイズしながら手軽にブログを開発するにはどの技術スタックにするかは最初の悩みポイントでした。

まずはヘッドレス CMS のサービスの利用を検討したんですが、API の使用確認やアプリケーションからの API 呼び出しの実装を考える点が手軽じゃないと感じて感じて他の方法を模索してました。

そんな時にタイミングよくNuxt Content V2がリリースされました。元々、Nuxt3 を使いたかったので、Nuxt Content を使ってブログを開発してみることになりました。

アプリケーションの構成

今回のアプリケーション構成は以下になります。

nuxt-content-blog
│
├─── content
│  └─── sample.md
│
├─── components
│  └─── content
│     └─── ProseCode.vue
│     └─── Card.vue
│
├─── composables
├─── layouts
├─── pages
│  └─── index.vue
│
├─── app.vue
└─── nuxt.config.ts

Nuxt Content のおすすめ機能

ファイルベースの CMS

ヘッドレス CMS は API の仕様確認や呼び出し実装が面倒くさいと感じていることに対して Nuxt Content は Markdown を指定のディレクトリに置くだけで簡単に静的コンテンツを生成することができます。 (Markdown の他に YML、CSV、JSON にも対応)

Nuxt3 のアプリケーションに ./content ディレクトリを作成して、その中に記事の Markdown ファイルを格納していきます。

nuxt-content-blog
│
├─── content <--- Markdownを格納する場所
│  └─── sample.md
・
・
・
# Hello Nuxt Content

Nuxt Content はいいぞ

ファイルを格納したら Page Component でContentDocを呼び出します。

/pages/index.vue
<template>
  <main>
    <ContentDoc />
  </main>
</template>

これだけで以下のような静的コンテンツを生成することができます。

ファイルベースCMSのサンプル

Prose Components

Markdown から静的コンテンツを生成する仕組みは以前からありましたが、各要素のカスタマイズがイマイチでした。 Nuxt Content のProse Componentsはシンプルな仕組みで手軽なカスタマイズ体験を得ることができます。

やり方はモジュール内部にある各要素ごとの Component と同じ名前の Component を作成することでオーバーライドすることができて、作成した Component にスタイルや機能追加などを実装するだけです。

Prose Components

例えば、コードブロックの右隅などにコードのコピーボタンを実装する場合は /components/content/ProseCode.vue を作成し、以下のようなコード書きます。

/components/content/ProseCode.vue
<script setup lang="ts">
import { useClipboard } from '~/composables/clipboard'

const { copy } = useClipboard()
const props = withDefaults(
  defineProps<{
    code: string | null
    language: string | null
    filename: string | null
    highlights: () => number[]
  }>(),
  {
    code: '',
    language: null,
    filename: null,
    highlights: () => [],
  }
)
</script>

<template>
  <div>
    <slot />
    <button @click="copy(code)">
      <font-awesome-icon icon="fa-solid fa-copy" />
    </button>
  </div>
</template>

MarkDown Components Syntax

ブログを書いていると動画や外部サービスのコンテンツの埋め込みが必要になることがあると思います。Markdown 記法だけでは実現できない要件に対してMarkDown Components Syntax(MDC)という Markdown 記法をサポートしてくれる機能があります。

使い方は/components/content/の配下に Component を作成して、::{Component名} という少し特殊な記法を記述するだけです。

nuxt-content-blog
│
├─── content
│  └─── sample.md
│
├─── components
│  └─── content
│     └─── Card.vue <--- これ
・
・
・
/components/content/Card.vue
<template>
  <div>
    <slot />
  </div>
</template>
# Hello Nuxt Content

Nuxt Content はいいぞ

::card
The content of the card
::

さいごに

Nuxt Content は Markdown 記法で簡単に記事が書ける点と Prose Components や MDC によるシンプルな仕組みかつカスタマイズ性が高い点において高い評価ができるモジュールだと思います。

また、Nuxt Content のおかげでこの Tech Blog のリリースが実現でき、無事に(無事じゃなかったけど)今年のアドベントカレンダーを実施することができました。

約 3 年ぶりに Vue Fes が開催されたり、先日 Nuxt3 の stable 版がリリースされたり、 これから Vue 界隈が益々盛り上がってくるはずなので、 面白いネタが見つかったらお伝えできればと思います。

ユアマイスターのアドベントカレンダーを引き続きよろしくお願いします!それでは!

ポストするはてなブックマークに追加シェアする