nuxt/content の記事の中で特定のタグの投稿リストを出せるようにしたい

たとえばこれとか

やりかた

Markdown は本文に HTML を使えますが、 components/content 以下に Vue ファイルを設置することで、その SFC も呼び出すことができるようになります。

なので、components/contnt 配下に、投稿リストを生成するためのコンポーネントをおいてあげればOKです。

components/content/EmbedPostList.vue

<script setup lang="ts">
import { PropType } from 'vue'

const { getTagNameBySlug } = usePostTags()
const props = defineProps({
  tag: {
    type: String,
    default: ''
  },
  limit: {
    type: Number,
    default: 0
  },
  orderBy: {
    type: String,
    default: 'createdAt'
  },
  order: {
    type: String as PropType<'asc'|'desc'>,
    default: 'desc'
  }
})

const posts = ref()

try {
  posts.value = await queryContent()
    .where({ tags: { $contains: props.tag } })
    .only(['title', '_path'])
    .sort({ [props.orderBy]: props.order === 'desc' ? -1 : 1 })
    .limit(props.limit)
    .find()
} catch (e) {
  posts.value = []
}
</script>

<template>
  <div class="post-list-embed">
    <ul v-if="posts.length > 0">
      <li
        v-for="post in posts"
        :key="post._path"
      >
        <NuxtLink :to="post._path">
          {{ post.title }}
        </NuxtLink>
      </li>
    </ul>
    <div v-else class="empty">
      NOT FOUND
    </div>
  </div>
</template>

つかいかた

あとは、本文から呼び出すだけです。
上にも書いたとおりで components/content に配置したコンポーネントは自動的に認識されるので、Importとかも不要です

<EmbedPostList tag="nuxt" order="asc" limit="3"></EmbedPostList>

注意点

どうも、閉じタグを省略した形 (<EmbedPostList />)だとうまく行かないようで、
閉じタグを必ずいれるようにします。

コンポーネントは正しくレンダリングされるように見えるけど、それ以降に書いた本文が表示されなくなってしまうようです。

git log --format=%ct:%s

:add post 2023021301