Đâ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
- Tạo thêm các bài viết và danh sách tag
- Thêm phân trang 5 bài/trang
- Viết layout
<BlogPost>
riêng để làm đẹp - Tạo custom component dùng trong Markdown
Thảo luận