Đăng nhập

BÀI 18: TRANG TAG ĐỘNG & LỌC BÀI VIẾT THEO CHỦ ĐỀ

Cùng tiếp tục với Bài 18 – Tạo trang Tag động và lọc bài viết theo chủ đề. Đây là bước cần thiết để tổ chức nội dung blog của bạn rõ ràng hơn, giúp người đọc dễ dàng tìm thấy các bài viết theo từng chủ đề cụ thể như “Vue”, “Nuxt”, “JavaScript”, “Performance”…


BÀI 18: TRANG TAG ĐỘNG & LỌC BÀI VIẾT THEO CHỦ ĐỀ


1. Mục tiêu bài học

  • Hiển thị danh sách tag
  • Tạo route động /tags/[tag].vue
  • Lọc bài viết theo tag tương ứng
  • Hiển thị giao diện đẹp, thân thiện SEO

2. Thêm tags vào bài viết Markdown

Trong content/blog/hello-nuxt.md:

---
title: Hello Nuxt
tags: ['nuxt', 'vue']
date: 2025-07-07
---

3. Tạo route động /tags/[tag].vue

Tạo file: pages/tags/[tag].vue

<script setup>
const route = useRoute()
const tag = route.params.tag

const { data: posts } = await useAsyncData(() =>
  queryContent('/blog')
    .where({ tags: { $contains: tag } })
    .sort({ date: -1 })
    .find()
)
</script>

<template>
  <section>
    <h1>Bài viết với tag: {{ tag }}</h1>

    <ul>
      <li v-for="post in posts" :key="post._path">
        <NuxtLink :to="post._path">{{ post.title }}</NuxtLink>
        <small>— {{ post.date }}</small>
      </li>
    </ul>

    <div v-if="!posts.length">
      <p>Không tìm thấy bài viết nào với tag này.</p>
    </div>
  </section>
</template>

4. Hiển thị danh sách tất cả tag

Tạo trang pages/tags/index.vue:

<script setup>
const { data: allPosts } = await useAsyncData(() =>
  queryContent('/blog').find()
)

const tags = computed(() => {
  const tagSet = new Set()
  for (const post of allPosts.value) {
    if (post.tags) {
      post.tags.forEach(tag => tagSet.add(tag))
    }
  }
  return Array.from(tagSet)
})
</script>

<template>
  <section>
    <h1>Tất cả chủ đề</h1>
    <ul>
      <li v-for="tag in tags" :key="tag">
        <NuxtLink :to="`/tags/${tag}`">#{{ tag }}</NuxtLink>
      </li>
    </ul>
  </section>
</template>

5. Gợi ý giao diện UX

  • Gắn badge màu cho mỗi tag
  • Sắp xếp tag theo bảng chữ cái hoặc tần suất
  • Hiển thị số bài viết trong mỗi tag

→ Nâng cao UX khi blog có nhiều chủ đề


6. Tối ưu SEO cho trang tag

Trong pages/tags/[tag].vue, thêm SEO:

<script setup>
definePageMeta({
  title: `Bài viết về ${tag}`,
  meta: [
    { name: 'description', content: `Tổng hợp bài viết liên quan đến ${tag}` },
    { property: 'og:title', content: `Tag: ${tag}` }
  ]
})
</script>

Bạn đã học được

  • Thêm tags cho từng bài viết Markdown
  • Tạo route động /tags/[tag].vue
  • Hiển thị danh sách bài viết theo tag
  • Tạo trang /tags liệt kê tất cả chủ đề
  • Áp dụng SEO cho từng tag

Bài tập mở rộng

  1. Làm component TagBadge.vue để tái sử dụng
  2. Hiển thị 5 tag phổ biến nhất trong sidebar
  3. Tạo route /categories/[slug].vue nếu dùng chuyên mục
  4. Gắn meta cho từng tag để tối ưu SEO nâng cao

Thảo luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Đăng ký nhận tin mới

Nhận bài học, tài nguyên và cơ hội việc làm qua email hàng tuần.

Chúng tôi cam kết không spam. Bạn có thể hủy bất cứ lúc nào.