Đăng nhập

BÀI 30: TẠO BLOG CMS VỚI NUXT CONTENT

Đây là bài cuối cùng trong chuỗi học Vue + Nuxt cơ bản. Hôm nay chúng ta sẽ cùng làm một blog CMS đơn giản sử dụng Nuxt Content, một tính năng cực kỳ mạnh mẽ giúp bạn viết bài bằng Markdown nhưng hiển thị như một hệ thống quản trị nội dung hiện đại.


1. Nuxt Content là gì?

  • Cho phép bạn viết bài bằng Markdown (.md) hoặc YAML, JSON
  • Không cần database
  • Hỗ trợ tự động routing, query, layout
  • Có thể kết hợp với SEO, phân trang, tag, search, v.v.

2. Cài đặt Nuxt Content

npm install @nuxt/content

Trong nuxt.config.ts:

export default defineNuxtConfig({
  modules: ['@nuxt/content']
})

3. Tạo thư mục content/blog

Tạo vài bài viết trong content/blog:

content/blog/hello-nuxt.md

---
title: Hello Nuxt Content
description: Đây là bài viết đầu tiên
date: 2024-06-01
tags: ['nuxt', 'blog']
---

# Chào mừng đến với Nuxt Content

Đây là nội dung Markdown của bài viết.

4. Hiển thị danh sách blog

pages/blog/index.vue

<template>
  <div>
    <h1>Danh sách bài viết</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>
</template>

<script setup>
const { data: posts } = await useAsyncData('blog', () =>
  queryContent('/blog').sort({ date: -1 }).find()
)
</script>

5. Hiển thị nội dung chi tiết bài viết

pages/blog/[slug].vue

<template>
  <article>
    <h1>{{ post.title }}</h1>
    <p><small>{{ post.date }}</small></p>
    <ContentRenderer :value="post" />
  </article>
</template>

<script setup>
const route = useRoute()
const { data: post } = await useAsyncData('post', () =>
  queryContent('/blog').where({ _path: `/blog/${route.params.slug}` }).findOne()
)
</script>

6. Tối ưu SEO từng bài viết

useSeoMeta({
  title: post.value.title,
  description: post.value.description,
  ogTitle: post.value.title,
  ogDescription: post.value.description
})

7. Giao diện nâng cao (gợi ý)

  • Thêm thẻ tag, categories
  • Phân trang bài viết
  • Sidebar bài viết mới nhất
  • Search bài viết bằng queryContent().search('vue')
  • Viết layout tùy chỉnh cho mỗi bài viết

8. Markdown nâng cao trong bài viết

Bạn có thể dùng:

  • Code block: “`js
    console.log(‘Hello Nuxt’)
    “`
  • Table, image, blockquote
  • Component trong Markdown:
<Alert type="info">Đây là thông báo</Alert>

→ Tự định nghĩa component <Alert /> trong components/.


9. Gợi ý cấu trúc CMS đơn giản

content/
├── blog/
│   ├── post1.md
│   ├── post2.md
├── about.md
├── contact.md

Tạo các trang /about, /contact từ content dễ dàng.


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

  • Cài và sử dụng Nuxt Content
  • Tạo blog bằng Markdown
  • Hiển thị danh sách + chi tiết bài viết
  • SEO tự động theo frontmatter
  • Viết layout Markdown chuyên nghiệp

Bài tập mở rộng

  1. Tạo thêm các bài viết và danh sách tag
  2. Thêm phân trang 5 bài/trang
  3. Viết layout <BlogPost> riêng để làm đẹp
  4. Tạo custom component dùng trong Markdown

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.