- Nuxt
Nuxt Content v3の使い方|ブログ実装コードと実行結果
Nuxt Content とは、content/ フォルダに置いた Markdown・YAML・JSON を、Nuxt のページやデータとして扱えるようにする公式モジュールです。 v3 ではビルド時に内容を SQLite(ファイル1つで動く軽量データベース)に取り込み、queryCollection('blog').where(...).order(...).all() のように SQL に近い書き方で取り出します。検索で見つかる解説には v1 の $content や v2 の queryContent()・<ContentDoc> を使ったものも多く、v3 では書き方が変わっています。
この記事では、@nuxt/content 3.16.1 + Nuxt 4.5.2 で Markdown ブログを一式作り、nuxt generate の出力とブラウザで一覧→詳細をたどった実行結果を載せます。同じコードが Nuxt 3.21.11 でも動くことも確認しました。SQLite で実際に出たエラーと直し方、v2 からの API 対応表もまとめています。
Nuxt Content v3 の早見表
| やりたいこと | 書き方(v3) | 補足 |
|---|---|---|
| 導入する | npm install @nuxt/content → modules: ['@nuxt/content'] |
Node 22.5 以上なら追加パッケージなしで SQLite を使える |
| 記事の置き場所と型を決める | content.config.ts で defineCollection({ type, source, schema }) |
type: 'page' は URL を持つ、'data' は持たない |
| URL から1件取る | queryCollection('blog').path(route.path).first() |
見つからないと null |
| 一覧を取る | queryCollection('blog').order('date', 'DESC').all() |
|
| 条件で絞る | .where('draft', '=', false) |
= <> > IN LIKE IS NULL など14種 |
| 必要な項目だけ取る | .select('title', 'path', 'date') |
一覧の転送量を減らせる |
| 件数・ページ送り | .count() / .skip(10).limit(10) |
|
| 本文を表示する | <ContentRenderer :value="page" /> |
v2 の <ContentDoc> の後継 |
| 前後の記事 | queryCollectionItemSurroundings('blog', path) |
[前, 次] の配列 |
| サイドナビ | queryCollectionNavigation('blog') |
フォルダ構造のツリー |
| 目次 | page.body.toc.links |
深さは build.markdown.toc で指定 |
| 記事内検索 | queryCollectionSearchSections('blog') |
見出し単位のセクション配列 |
| Markdown に Vue を置く | ::note … :: と components/content/Note.vue |
MDC 構文 |
| コードに色を付ける | build.markdown.highlight.theme |
Shiki で出力時に色付け |
| 静的サイトにする | npx nuxt generate |
ブラウザ側は WASM 版 SQLite で問い合わせ |
取得系の関数は useAsyncData の中で呼ぶのが基本です(サーバーでの取得結果がページに埋め込まれ、二重取得を防げます)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Nuxt Content v3の使い方|ブログ実装コードと実行結果」
動作環境とバージョン(2026年9月時点)
| 項目 | この記事で使った版 | 確認したこと |
|---|---|---|
| @nuxt/content | 3.16.1(npm の latest) | モジュールの対応範囲は nuxt: ">=4.1.0 || ^3.19.0" |
| Nuxt | 4.5.2 と 3.21.11 | 同じコードで両方とも generate と画面確認が通過 |
| Node.js | 22.22.2 | Nuxt 4.5.2 は Node 22.19 以上が必要 |
| スキーマ | zod 3.25.76(同梱) | import { z } from '@nuxt/content' |
| SQLite | Node 標準の node:sqlite |
experimental.sqliteConnector: 'native' で指定 |
完成形のファイル構成と仕組み
content-blog/
├── nuxt.config.ts
├── content.config.ts # コレクション定義
├── content/
│ ├── blog/
│ │ ├── 1.getting-started.md
│ │ ├── 2.collections.md
│ │ ├── 3.mdc-components.md
│ │ └── 4.draft.md # draft: true
│ └── authors/
│ └── sato.yml
└── app/
├── app.vue
├── layouts/default.vue # サイドナビ
├── components/content/Note.vue
└── pages/
├── index.vue # 記事一覧
├── blog/[...slug].vue # 記事詳細
├── tags/[tag].vue # タグ絞り込み
└── search.vue # 記事内検索
flowchart LR
A[content/*.md, *.yml] -->|ビルド時に解析| B[(SQLite)]
B -->|queryCollection| C[サーバーで描画]
B -->|generate 時に sql_dump.txt| D[ブラウザの WASM SQLite]
D -->|ページ移動時の問い合わせ| E[クライアントで描画]
v3 の要点は「Markdown を一度 SQLite に入れてから問い合わせる」ことです。静的サイトでも、ページ移動時はブラウザ側の SQLite(WebAssembly 版)が動くため、同じ queryCollection が使えます。
手順1:インストールと SQLite の準備
npm install @nuxt/content
// nuxt.config.ts
export default defineNuxtConfig({
compatibilityDate: '2025-07-15',
devtools: { enabled: false },
modules: ['@nuxt/content'],
content: {
experimental: { sqliteConnector: 'native' },
build: {
markdown: {
toc: { depth: 3, searchDepth: 3 },
highlight: {
theme: 'github-light',
langs: ['ts', 'vue', 'bash', 'json'],
},
},
},
},
})
SQLite の接続方法を選ぶ
最初は experimental.sqliteConnector を書かずに nuxt prepare を実行しました。既定の better-sqlite3 パッケージが入っていないため、次のエラーで止まります(実行結果)。
[@nuxt/content] ERROR Nuxt Content requires better-sqlite3 module to operate. Please install better-sqlite3 package manually and try again. npm install better-sqlite3
直し方は2つです。Node 22.5 以上なら sqliteConnector: 'native' を指定するのが手軽で、追加パッケージなしで node:sqlite が使われます。上の設定で nuxt prepare と nuxt generate が通りました。
接続方法(sqliteConnector) |
追加パッケージ | 向いている環境(公式ドキュメントより) |
|---|---|---|
'better-sqlite3'(既定) |
better-sqlite3 |
Node 全般(StackBlitz・Bun は対象外) |
'native' |
不要(Node 22.5.0 以上) | Node 標準の node:sqlite を使う |
'sqlite3' |
sqlite3 |
Node、StackBlitz など |
'bun' |
不要 | Bun ランタイム |
以前の experimental.nativeSqlite: true は非推奨です。
better-sqlite3 を使う場合の「bindings」エラー
better-sqlite3 はネイティブモジュール(C++ で書かれた部品)です。v12 をインストールスクリプトなしで入れる(pnpm v10 の既定の動きや --ignore-scripts と同じ状態)と、ビルド時に次のエラーになりました(npm i --ignore-scripts better-sqlite3@12 のあと nuxt generate、パスは短縮)。
ERROR Could not locate the bindings file. Tried:
→ .../node_modules/better-sqlite3/build/better_sqlite3.node
...
at async getLocalDatabase (node_modules/@nuxt/content/dist/module.mjs:344:7)
| 状況 | 対処 |
|---|---|
| npm で入れた | npm rebuild better-sqlite3(この環境では rebuilt dependencies successfully で解消) |
| pnpm v10 以上 | package.json の pnpm.onlyBuiltDependencies に better-sqlite3 を追加して pnpm rebuild better-sqlite3(公式の手順) |
| 手早く済ませたい | sqliteConnector: 'native' に切り替える |
なお、better-sqlite3 の最新 13.0.3 は各OS向けのビルド済みファイルを同梱しており、この環境ではそのまま動きました。
手順2:content.config.ts でコレクションを定義する
コレクションとは「どのファイルを、どんな型のデータとして読むか」の定義です。v3 ではこれが必須になりました。
// content.config.ts
import { defineCollection, defineContentConfig, z } from '@nuxt/content'
export default defineContentConfig({
collections: {
// 記事:1ファイル = 1ページ(path が自動で付く)
blog: defineCollection({
type: 'page',
source: 'blog/*.md',
schema: z.object({
date: z.string(),
tags: z.array(z.string()).default([]),
author: z.string(),
draft: z.boolean().default(false),
}),
}),
// 著者:ページを持たないデータ
authors: defineCollection({
type: 'data',
source: 'authors/*.yml',
schema: z.object({
name: z.string(),
slug: z.string(),
bio: z.string(),
}),
}),
},
})
| 設定 | 意味 | 例 |
|---|---|---|
type: 'page' |
URL を持つ記事。path・title・description・body・navigation などが自動で付く |
ブログ、ドキュメント |
type: 'data' |
URL を持たないデータ。スキーマに書いた項目だけ | 著者、設定、FAQ |
source |
content/ からの glob(ファイルの一致パターン) |
'blog/*.md'、'**/*.md' |
schema |
frontmatter(Markdown 先頭の --- の間)の項目と型 |
z.string()、z.array(...) |
スキーマに書いた項目はクエリ結果に型が付きます。 この記事のコードは nuxt typecheck でエラー0件でした。
スキーマは「型と保存する列」の定義で、必須項目が欠けてもビルドは止まりません。 試しに date と author を書かない記事を追加して nuxt generate すると、エラーなしで出力され、一覧の日付欄が空になりました(' / x' と表示)。抜けやすい項目は .default() を付けるか、公開前のチェックで確認すると安心です。
手順3:記事ファイルを書く
---
title: コレクションとスキーマ
description: content.config.ts で型つきのコレクションを定義します。
date: '2026-09-08'
tags: [content, typescript]
author: sato
---
## コレクションを定義する
`defineCollection` で `type` と `source` と `schema` を指定します。
```ts [content.config.ts]
blog: defineCollection({
type: 'page',
source: 'blog/*.md',
})
```
::note{type="tip"}
スキーマに書いた項目は、クエリの結果に**型つき**で入ります。
::
## data コレクション
YAML や JSON を `type: 'data'` で読み込めます。
# content/authors/sato.yml
name: 佐藤 花子
slug: sato
bio: フロントエンドとドキュメント整備が好きなエンジニア。
ファイル名の先頭の 1. 2. は並び順にだけ使われ、URL からは消えます(1.getting-started.md → /blog/getting-started)。見出しには id="インストール" のような id が付き、目次に入ります。他の3記事も同じ形式で、4.draft.md だけ draft: true です。
手順4:記事一覧ページ(queryCollection)
<!-- app/pages/index.vue -->
<script setup lang="ts">
const { data: posts } = await useAsyncData('blog-list', () =>
queryCollection('blog')
.where('draft', '=', false)
.order('date', 'DESC')
.select('title', 'description', 'path', 'date', 'tags')
.all(),
)
</script>
<template>
<div>
<h1>記事一覧</h1>
<article v-for="post in posts" :key="post.path" data-testid="post">
<NuxtLink :to="post.path"><h2>{{ post.title }}</h2></NuxtLink>
<p>{{ post.date }} / {{ post.description }}</p>
<NuxtLink v-for="tag in post.tags" :key="tag" :to="`/tags/${tag}`">#{{ tag }}</NuxtLink>
</article>
</div>
</template>
実行結果:下書きを除いた 3件が新しい順 に並びました。
一覧の記事数 : 3
一覧の先頭 : MDC 構文で Vue コンポーネントを使う
クエリビルダーのメソッド一覧
| メソッド | 役割 | 例 |
|---|---|---|
path(path) |
URL で1件に絞る | .path('/blog/collections') |
where(field, op, value) |
条件(重ねると AND) | .where('date', '>=', '2026-09-01') |
andWhere(g => ...) / orWhere(g => ...) |
条件のグループ | .orWhere(g => g.where('tags', 'LIKE', '%vue%').where('tags', 'LIKE', '%nuxt%')) |
order(field, 'ASC' | 'DESC') |
並べ替え | .order('date', 'DESC') |
select(...fields) |
取り出す項目を限定(戻り値の型も絞られる) | .select('title', 'path') |
skip(n) / limit(n) |
ページ送り | .skip(10).limit(10) |
all() |
配列で取得 | |
first() |
1件(なければ null) |
|
count(field?, distinct?) |
件数 | .count() |
使える演算子は = >= <= > < <> IN NOT IN BETWEEN NOT BETWEEN IS NULL IS NOT NULL LIKE NOT LIKE の14種です。
手順5:記事詳細ページ([...slug].vue と ContentRenderer)
<!-- app/pages/blog/[...slug].vue -->
<script setup lang="ts">
const route = useRoute()
const { data: page } = await useAsyncData(route.path, () =>
queryCollection('blog').path(route.path).where('draft', '=', false).first(),
)
if (!page.value) {
throw createError({ statusCode: 404, statusMessage: 'Page not found', fatal: true })
}
const { data: author } = await useAsyncData(`author-${page.value.author}`, () =>
queryCollection('authors').where('slug', '=', page.value!.author).first(),
)
const { data: surround } = await useAsyncData(`${route.path}-surround`, () =>
queryCollectionItemSurroundings('blog', route.path, { fields: ['description'] })
.where('draft', '=', false),
)
useSeoMeta({ title: page.value.title, description: page.value.description })
</script>
<template>
<article v-if="page">
<h1>{{ page.title }}</h1>
<p data-testid="author">{{ author?.name }} / {{ page.date }}</p>
<nav data-testid="toc">
<ul>
<li v-for="link in page.body.toc?.links" :key="link.id">
<a :href="`#${link.id}`">{{ link.text }}</a>
<ul v-if="link.children">
<li v-for="child in link.children" :key="child.id">
<a :href="`#${child.id}`">{{ child.text }}</a>
</li>
</ul>
</li>
</ul>
</nav>
<ContentRenderer :value="page" />
<nav data-testid="surround">
<NuxtLink v-if="surround?.[0]" :to="surround[0].path">← {{ surround[0].title }}</NuxtLink>
<NuxtLink v-if="surround?.[1]" :to="surround[1].path">{{ surround[1].title }} →</NuxtLink>
</nav>
</article>
</template>
実行結果(一覧から「コレクションとスキーマ」をクリックして遷移):
詳細 URL : /blog/collections
詳細 h1 : コレクションとスキーマ
著者 : 佐藤 花子 / 2026-09-08
目次 : コレクションを定義する | data コレクション
Note 描画 : 1 / ヒントスキーマに書いた項目は、クエリの結果に型つきで入ります。
ハイライト : 4 行 / class= language-ts shiki shiki-themes github-light
前後リンク : ← Nuxt Content を始める | MDC 構文で Vue コンポーネントを使う →
| ポイント | 理由 |
|---|---|
useAsyncData のキーに route.path |
記事ごとに別のキャッシュにするため。キーが固定だと、記事を移動したときに前の記事のデータを使い回すことがある |
| 見つからないときは 404 | 空ページを200で返さない |
| 著者は data コレクションから取得 | 表示名は YAML 側で一元管理 |
前後記事は [前, 次] の配列 |
先頭の記事では surround[0] が null。.where() で下書きも除ける |
目次は page.body.toc.links |
toc.depth: 3 なので ### が children に入る |
手順6:タグで絞り込む
<!-- app/pages/tags/[tag].vue -->
<script setup lang="ts">
const route = useRoute()
const tag = String(route.params.tag)
// tags は配列なので、SQLite 上では JSON 文字列として保存される
const { data: posts } = await useAsyncData(`tag-${tag}`, () =>
queryCollection('blog')
.where('tags', 'LIKE', `%"${tag}"%`)
.where('draft', '=', false)
.order('date', 'DESC')
.all(),
)
</script>
<template>
<div>
<h1>#{{ tag }} の記事</h1>
<NuxtLink v-for="post in posts" :key="post.path" :to="post.path" data-testid="tag-post">
{{ post.title }}
</NuxtLink>
</div>
</template>
#content : MDC 構文で Vue コンポーネントを使う | コレクションとスキーマ | Nuxt Content を始める
配列は SQLite に ["content","vue"] のような JSON 文字列で入るため、ダブルクォートごと LIKE で探すと vue と vuex の部分一致を避けられます。
手順7:サイドナビ(queryCollectionNavigation)
<!-- app/layouts/default.vue -->
<script setup lang="ts">
const { data: navigation } = await useAsyncData('navigation', () =>
queryCollectionNavigation('blog').where('draft', '=', false),
)
</script>
<template>
<div>
<nav data-testid="nav">
<NuxtLink to="/">記事一覧</NuxtLink>
<template v-for="item in navigation" :key="item.path">
<NuxtLink v-for="child in item.children" :key="child.path" :to="child.path">
{{ child.title }}
</NuxtLink>
</template>
</nav>
<main><slot /></main>
</div>
</template>
ナビ : 記事一覧 | Nuxt Content を始める | コレクションとスキーマ | MDC 構文で Vue コンポーネントを使う
ナビはフォルダ単位のツリーで返ります(/blog の children に各記事)。フォルダの表示名は .navigation.yml に書きます。
直す前と後:下書きが静的出力に入った
最初はナビに条件を付けておらず、nuxt generate のクローラー(リンクをたどって出力する機能)が /blog/draft まで HTML として出力しました。
[nitro] ├─ /blog/draft (128ms)
ナビと詳細ページの両方に .where('draft', '=', false) を付けたところ、出力から消え、/blog/draft へのアクセスは 404 になりました。一覧だけでなく「リンクが生まれる場所」すべてで絞るのがポイントです。
手順8:記事内検索(queryCollectionSearchSections)
<!-- app/pages/search.vue -->
<script setup lang="ts">
const q = ref('')
const { data: sections } = await useAsyncData('search-sections', () =>
queryCollectionSearchSections('blog'),
)
const results = computed(() => {
const word = q.value.trim()
if (!word) return []
return (sections.value ?? []).filter(
(s) => s.title.includes(word) || s.content.includes(word),
)
})
</script>
<template>
<div>
<h1>記事内検索</h1>
<input v-model="q" data-testid="q" placeholder="キーワード">
<ul>
<li v-for="s in results" :key="s.id" data-testid="hit">
<NuxtLink :to="s.id">{{ [...s.titles, s.title].join(' > ') }}</NuxtLink>
</li>
</ul>
</div>
</template>
検索「スキーマ」: コレクションとスキーマ | コレクションとスキーマ > コレクションを定義する
queryCollectionSearchSections は記事を見出しごとのセクション(id・title・titles・level・content)に分けて返します。 id は見出しへのリンク(/blog/collections#...)なので、そのまま NuxtLink に渡せます。記事が多い場合は、この配列を Fuse.js などの検索ライブラリに渡す構成も使えます。
手順9:MDC 構文とカスタムコンポーネント
MDC(Markdown Components)とは、Markdown の中に Vue コンポーネントを書ける記法です。app/components/content/ に置いたコンポーネントが Markdown から使えます。
<!-- app/components/content/Note.vue -->
<script setup lang="ts">
defineProps<{ type?: 'tip' | 'warning' }>()
</script>
<template>
<div class="note" :data-type="type ?? 'tip'">
<strong>{{ type === 'warning' ? '注意' : 'ヒント' }}</strong>
<slot />
</div>
</template>
| 書きたいもの | MDC の書き方 |
|---|---|
| ブロックのコンポーネント | ::note 改行 本文 改行 :: |
| props を渡す | ::note{type="warning"} |
| インラインのコンポーネント | :badge{text="新着"} |
| 文字にクラスを付ける | [属性]{.accent} |
| 名前付きスロット | コンポーネント内で #title の行を書く |
コンポーネント名はファイル名と対応します(Note.vue → ::note)。実行結果では、Markdown の ::note{type="tip"} が <div class="note"> として描画され、中の太字も保たれました。
手順10:コードハイライト
コードの色付けは Shiki(VS Code と同じ文法定義を使うライブラリ)がビルド時に行います。 出力された <pre> には class="language-ts shiki shiki-themes github-light" が付きました。
| 設定 | 内容 |
|---|---|
theme: 'github-light' |
1つのテーマ |
theme: { default: 'github-light', dark: 'github-dark' } |
ダークモード用を追加 |
langs |
追加する言語。既定は json js ts html css vue shell mdc md yaml |
nuxt generate の出力と画面確認
npx nuxt generate
実行ログ(抜粋、Nuxt 4.5.2):
[nitro] i Prerendering 5 initial routes with crawler
[nitro] ├─ /__nuxt_content/authors/sql_dump.txt (110ms)
[nitro] ├─ /__nuxt_content/blog/sql_dump.txt (113ms)
[nitro] ├─ / (117ms)
[nitro] ├─ /tags/content (108ms)
[nitro] ├─ /blog/collections (117ms)
[nitro] i Prerendered 22 routes in 2.693 seconds
| 出力 | 役割 |
|---|---|
blog/collections/index.html と _payload.json |
各ページの HTML と、ページ移動時のデータ |
__nuxt_content/blog/sql_dump.txt |
ブラウザ側 SQLite に読み込む中身 |
_nuxt/sqlite3.*.wasm(864,752 バイト) |
ブラウザで動く SQLite 本体 |
| 合計 | .output/public で 1.9MB |
静的出力でもページ移動時の queryCollection がブラウザで動くのは、この sql_dump.txt と WASM を読み込むためです。開発サーバーでは .data/content/contents.sqlite が作られ、起動時に [@nuxt/content] √ Processed 3 collections and 5 files in 334.55ms と表示されました。
Playwright で一覧→詳細を確認する
.output/public を静的サーバーで配信し、Playwright 1.56(Chromium)で「一覧を開く → 記事をクリック → 詳細の見出し・目次・前後リンクを読む → /blog/draft を直接開く」を実行しました。手順4〜8に載せた実行結果はこのスクリプトの出力で、/blog/draft は 404 でした。Nuxt 4.5.2 と Nuxt 3.21.11 の両方で、すべての項目が同じ結果になりました。
v2 から v3 への API 対応表
公式の移行ガイドで確認した対応です。Markdown ファイル自体は書き換え不要で、呼び出し側のコードを置き換えます。
| v2 | v3 |
|---|---|
queryContent() |
queryCollection() |
queryContent(path).findOne() |
queryCollection('content').path(path).first() |
queryContent().findSurround(path) |
queryCollectionItemSurroundings('content', path) |
fetchContentNavigation() |
queryCollectionNavigation() |
searchContent() |
queryCollectionSearchSections() |
<ContentDoc> |
<ContentRenderer>(取得は自分で書く) |
<ContentList> / <ContentNavigation> / <ContentQuery> |
なし(上のクエリ関数で取得して描画) |
<ContentSlot> / <MDCSlot> |
Vue 標準の <slot> |
useContent() / useContentHelpers() |
なし |
import type { NavItem } |
import type { ContentNavigationItem } |
_dir.yml |
.navigation.yml |
._path |
.path |
設定なしで content/ 全体を読む |
content.config.ts でコレクション定義が必要 |
書き方が変わった点の注意:
- 並び順の既定が数値順からアルファベット順に変わりました。
order()を明示すると確実です。 - ドットで始まるファイルも既定で読み込まれます。除外したい場合は
sourceのexcludeで指定します。 - v2 のまま
queryContentを残すと、nuxt typecheckでerror TS2304: Cannot find name 'queryContent'.と表示されました。型チェックで置き換え漏れを一覧にできます。
よくあるエラーと対処(実際に出たもの)
| 出たメッセージ・現象 | 原因 | 対処 |
|---|---|---|
Nuxt Content requires better-sqlite3 module to operate. |
既定の接続方法のパッケージがない | sqliteConnector: 'native' か npm install better-sqlite3 |
Could not locate the bindings file. |
better-sqlite3 のネイティブ部分が未ビルド | npm rebuild better-sqlite3、pnpm は onlyBuiltDependencies |
Cannot find name 'queryContent'. |
v2 の API が残っている | 上の対応表で置き換え |
| 下書きが静的出力に入る | ナビや前後記事のリンクから辿られた | リンクを作る全クエリに .where('draft', '=', false) |
| 一覧の日付が空 | frontmatter の書き忘れ(ビルドは通る) | .default() や公開前チェック |
よくある質問
Q. Nuxt 3 のプロジェクトでも Content v3 は使えますか?
A. 使えます。@nuxt/content 3.16.1 の対応範囲は >=4.1.0 || ^3.19.0 で、この記事のコードは Nuxt 3.21.11 でも generate と画面確認が同じ結果になりました。Nuxt 3 では app/ を作らず、中身をプロジェクト直下に置きます。
Q. SQLite のサーバーを用意する必要はありますか? A. 不要です。Node ではファイル1つのデータベースが自動で作られ、静的出力ならブラウザ側で WASM 版が動きます。サーバーレス環境向けに D1・PostgreSQL・LibSQL なども選べます。
Q. native と better-sqlite3 はどちらを選べばよいですか?
A. Node 22.5 以上で追加パッケージを増やしたくないなら native が手軽です。既存の CI やデプロイ先で better-sqlite3 の動作実績がある場合はそのままでも問題ありません。どちらでもクエリの書き方は同じです。
まとめ
- v3 は Markdown を SQLite に取り込み、
queryCollection()で取り出す仕組み content.config.tsのコレクション定義が必須。記事はtype: 'page'、URL のないデータはtype: 'data'- 一覧は
where/order/select/all、詳細はpath().first()+<ContentRenderer> - 前後記事・ナビ・検索は
queryCollectionItemSurroundings/queryCollectionNavigation/queryCollectionSearchSections - SQLite のエラーは
sqliteConnector: 'native'か better-sqlite3 の再ビルドで解消 - 下書きはリンクが生まれるすべてのクエリで除外すると、静的出力にも入らない
- Nuxt 4.5.2 と 3.21.11 の両方で同じコードが動作。v2 からは対応表どおりに置き換え
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Nuxt Content v3の使い方|ブログ実装コードと実行結果」
株式会社RJCでは、Markdownでの情報発信やドキュメント整備に使える技術を、実際に動かして確かめながらプロジェクトの中で共有しています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。