PublishedDate: 18 March 2025

Nuxt v3 讓網頁支援 markdown

目前有兩個主要版本 @nuxt/content v2 和 v3 , v2 版本只要安裝好不用設定就可以使用,至於 v3 安裝好後假如不設定幾乎無法使用,還有很多語法也變更了,網路上多數的 教學幾乎不註明使用的是哪一版本,很容易搞混,再加上官方的說明沒有很明確,試用了半天用不出來,換到 v2 很快上手,又換到 v3 試了幾小時後才知道問題出在哪裡。

content v2 與 v3 比較

目錄結構如下

content
  markdown-demo.md
  about.md
  blog
  price

當所有的 markdown 檔案都有以下的 meta 資料,第二版會自動產生,第三版也會產生但是

---
description: Nuxt + markdown
category: nuxt
tags: 
 - nuxt
 - nuxt@content
 - vue 
 - markdown
 - static website
 - 靜態網站
 - 前端
published: true
publishedDate: 15 March 2025
updatedDate: 
---

# z5525 主題

<!-- 以下省略 -->

第二版中 queryContent("content") 可以找到 content 目錄之下所有的 *.md , published 就 是自己定義的 meta 資料(在檔案頭兩個---之間的欄位)。

pages/index.vue
// content v2
// pages/index.vue
const { data: posts } = await useAsyncData("posts", () => {
  return queryContent("content")
    .where({published: true })
    .limit(pageSize)
    .find();
})

再來看看第三版,語法改變很多,用第二版本的查詢語法 queryCollection('content'),結果是沒有數據,但是還有一個問題,會顯示錯誤沒有 published 欄位,這是什麼情形,因為在 content.config.ts 沒有定義這個欄位。

// content v3
// pages/index.vue
const { data: posts } = await useAsyncData('posts', () => {
  return queryCollection('content')
    .where('published', '=', true)
    .limit(pageSize)
    .order('id', 'ASC') // ASC|DESC 一定要大寫
    .all();
})

我們來看看第三版 queryCollection 會產生什麼數據,看看附件 content v3.x queryCollection 原始數據 我們定義的會包在 meta 之內,那 where 可以搜尋 meta 內的欄位嗎?好像是不行,官網沒有寫。改用另一個方法定義數據 content.config.ts 範例如下。

看附件 content v3.x queryCollection 定義之後的數據 ,有定義的欄位會被搬出來,但是在 meta 的欄位不見了,好怪的邏輯,這樣作法程式和設定綁得死死的,,只要變動欄位新增欄位也會增加變動成本。

content.config.ts
// content.config.ts
import { defineCollection, defineContentConfig, z } from '@nuxt/content'
export default defineContentConfig({
  collections: {
    docs: defineCollection({
      // Load every file inside the `content` directory
      source: '**',
      // Specify the type of content in this collection
      type: 'page',
      schema: z.object({
        published: z.boolean().default(false)
      })
    }),
  }
})
// content v3.x queryCollection 原始數據
{
    "id": "docs/nuxt3/01.nuxtv3.md",
    "title": "Nuxt v3 簡易使用教學",
    "body": {},
    "description": "Nuxt v3 使用教學範例",
    "extension": "md",
    "meta": {
        "category": "nuxt",
        "tags": [
            "nuxt",
            "vue",
            "前端"
        ],
        "published": true,
        "publishedDate": "13 March 2025",
        "updatedDate": null,
    },
    "navigation": true,
    "path": "/nuxt3/nuxtv3",
    "seo": {
        "title": "Nuxt v3 簡易使用教學",
        "description": "Nuxt v3 使用教學範例"
    },
    "stem": "nuxt3/01.nuxtv3",
    "__hash__": "CQ7sbnHy3C"
}
// content v3.x queryCollection 定義之後的數據
{
    // 略
    "tags": [
        "nuxt",
        "vue",
        "前端"
    ],
    "published": true,
    "meta": {
        "category": "nuxt",
        "publishedDate": "13 March 2025",
        "updatedDate": null,
    },
    // 略
}

也變更名稱第三版叫做 path,第二版叫做 _path

版本備註

@nuxt/content v2.13.4
@nuxt/content v3.3.0