Nuxt Contentについて調べたことまとめ
Nuxt Contentとは
"Content made easy for Vue Developers"(Vue開発者が簡単にコンテンツを作成できる)と公式サイトが歌っている、Markdownファイルを簡単にwebサイトにできる優れたNuxt.js用モジュール。Nuxt3からSSG(静的ジェネレート)に対応したため、静的サイトとしても作成可能になった。
Nuxt Contentの特徴
- MarkdownをHTMLに変換
- シンタックスハイライト機能あり
- Markdown内でVueコンポーネント利用可能
- コンテンツ(Markdown/json/csv等)内のデータをQueryBuilderAPIを使って取得可能
- 目次の生成
いわゆるWordPress等のCMSと違ってMarkdownやyamlといったファイルをベースに記事を作成する。またWordPressでVueを使う場合にはheadless api化するなど手間がかかるが、Nuxt.jsがベースで、MDC (Markdown Components) と呼ばれるMarkdownからコンポーネントを呼び出す記法が可能なため特に準備をすることもなく始めることができる。
参考記事
Nuxt Contentの始め方
各々前提バージョン
- Nuxt.js: 3.12.3
- @nuxt/content: 2.13.1
インストール
新規で始める場合はターミナル上で以下を実行する。
npx nuxi@latest init content-app -t content
フォルダ構成
Nuxt Contentの主なフォルダ構成は以下のようになる。
|_.nuxt
|_assets
|_components
|_content
|_content
|_layouts
|_pages
|_public
|_server
特徴的なのは、root直下のcontent
フォルダと、componentsフォルダ直下のcontent
フォルダになる。
root直下のcontent
フォルダには、記事化したいmarkdownファイルを配置する。例えば以下のように配置する。
|_content
|_blog
|_news
|_1.md
|_vue
|_1.md
そのあと、pages配下に以下の記載をする。
pages/news/[...slug].vue
<template>
<main>
<ContentDoc />
</main>
</template>
pages/vue/[...slug].vue
<template>
<main>
<ContentDoc />
</main>
</template>
Nuxt Content独自のタグであるContentDocにmarkdownの文字列が割り当てられ、/blog/news/1
と/blog/vue/1
にアクセスできるようになる。
参考記事
特定の記事内容に独自のコンポーネントを割り当てるには?
Nuxt ContentにはMDC (Markdown Components) と呼ばれるMarkdownからコンポーネントを呼び出す記法が使える。
ピュアなmarkdownファイルではなくなるものの、ファイル内に特定の記載をすることで記事の特定箇所で特定のスタイルを割り当てることが可能になる。
例えば以下のように変化させたい文字列をmarkdown上で:: ::
を使って括る。
::card
The content of the card
::
componentsフォルダ直下のcontent
フォルダから、Card.vueと書かれたコンポーネントを探し、割り当てて見た目を変えることができる。
また、全てのpタグに同じコンポーネントを当てたいといった場合にはnuxt.config.tsを操作することで可能になる。
export default defineNuxtConfig({
// 一部省略
content: {
markdown: {
tags: {
p: "Paragraph",
h2: "H2Headline",
},
},
},
})
上記だとpタグにcomponents/content
配下にあるParagraph.vueを割り当てる指示をしている。
参考記事
記事一覧のページを作るには?
例えばブログサイトだと、以下のようなブログの記事一覧が並んでいるのが一般的である。
このような記事一覧を作るにはuseAsyncData
とqueryContent
を活用する。
Nuxt Contentではフロントマターを利用してページそれぞれに特定のカテゴリやタグをつけることが可能になる。
例えば以下のように指定するとtitleとdescriptionが割り当てられ、queryContent
を使うことで値を取りだすことが可能になる。
---
title: 'Title of the page'
description: 'meta description of the page'
---
以下のようにuseAsyncData
とqueryContent
を使って/blog
配下のフロントマターを取り出すことができる。
<script setup>
const { data: news } = await useAsyncData("news", () =>
queryContent("/blog").sort({ published: -1 }).find()
);
console.log(news.value);
</script>
参考記事/コード