layout | highlighter | css | colorSchema | transition |
---|---|---|---|---|
shiki |
unocss |
dark |
fade-out |
Speaker at VueJs Kenya.
Creator of Windi UI , Nuxt UI Vue and MarkQuest
Open source contributor.
The Nuxt Content Module is an official module created by the Nuxt team that provides a powerful data layer for your Nuxt 3 application.
It enables you to write your content in the `content` directory and fetch them using an API with a MongoDB like syntax with the help of the queryContent() composable.
It supports various formats that you can write your content in such as:
- Markdown
- JSON
- YAML
- CSV
- etc
Using the CLI
Using the nuxi CLI
Using the Nuxt Devtools
Using the Nuxtr VSCode extension
Add the module
- What is the content directory?
This is where we write our content using a file which has a `.md` extension
The content module has a feature that NuxtJs and NextJs share.
That feature is known as file-based routing but in our case we will call it content-based routing because we are using the content directory.
Where each file is a path generated by the content module according to the directory structure
- How do we write our content in a .md file?
Let's start from the top
1. Front-matter
The Front-matter uses the YAML syntax with key-value pairs to provide meta-data to pages.
---
title: 'Nuxt Content Module Talk'
description: 'Selemondev is giving a talk about the Nuxt Content Module'
head:
meta:
- name: 'keywords'
content: 'nuxt-content, vuejs-kenya, nuxt3'
- name: 'author'
content: 'Selemondev'
---
Under the hood the useContentHead() composable is utilized to set the page's meta-data
That becomes this:
<head>
<meta charset="UTF-8">
<meta name="description" content="Selemondev is giving a talk about the Nuxt Content Module">
<meta name="keywords" content="nuxt-content, vuejs-kenya, nuxt3">
<meta name="author" content="Selemondev">
<title>Nuxt Content Module Talk</title>
</head>
If you want to use images in your markdown, you can place the images in the `public` directory and use it as such:
![VueJs-Kenya](/vuejs-kenya.png)
or you can check out the Nuxt Content Assets module built by Dave Stewart for relative media path references.
- How do we fetch our contents?
By using the useAsyncData() composable provided by Nuxt together with the queryContent() composable provided by the Nuxt Content module
const { data } = useAsyncData(() => queryContent('/'))
The queryContent() composable provides us with methods for querying and fetching our contents.
These methods include:
- find() - Returns all the content
- only() - Returns only the selected subset of fields
- findOne()
- without() - Returns the result with a subset of fields removed
- limit() - Returns all only the number of result(s) specified
- count() - Returns the numbers of articles of a given path
- skip() - Skip the specified number of results
- where() - Filter the results by query
- etc
const { data } = useAsyncData(() =>
queryContent('/')
.only(['author', "_path", "title", "description", "date"])
.sort({
date: -1
})
.limit(1)
.find()
)
const { data } = useAsyncData(() =>
queryContent('/blog')
.only(['author', "_path", "title", "description", "date"])
.count()
)
- How do we fetch our contents?
By using the ContentQuery renderless component by the Nuxt Content module.
<template>
<div>
<ContentQuery query="/blog" :only="['_path', 'title', 'description', 'date']" v-slot="{ data }">
<pre>{{ data }}</pre>
</ContentQuery>
</div>
</template>
The ContentQuery renderless component shortens the access to the queryContent() composable.
- How do we render our content?
By using the ContentDoc component provided by the Nuxt Content module.
The ContentDoc component fetches and display the markdown component based on the current path.
<template>
<div class="m-auto">
<ContentDoc class="dark:text-white " />
</div>
</template>
- What are the components provided by the Nuxt Content module?
This component fetches a list of documents and allows you to render them by using slots:
<template>
<div>
<ContentList path="/blog" :only="['_path']" v-slot="{ list }">
<pre>{{ list }}</pre>
</ContentList>
</div>
</template>
This component is a renderless component that shortens the access to the navigation.
<template>
<div>
<ContentNavigation path="/blog" v-slot="{ navigation }">
<pre>{{ navigation }}</pre>
</ContentNavigation>
</div>
</template>
This component makes it easier to use Markdown syntax in your Vue components.