params.slug
to fetch contentCreate a articles
folder inside pages
Create a _slug.vue
file
The template is similar.
<template>
<div>
<nuxt-content :document="post" />
</div>
</template>
Some changes in script
, using params.slug
:
export default {
async asyncData ({ $content, params }) {
const post = await $content('articles', params.slug).fetch()
return { post }
}
}
The first article I created was content/articles/nuxt-content-ssg.md
.
To see it visit /articles/nuxt-content-ssg.
You should see the content you created.
/articles
We want to create a list of articles.
Create an index.vue
file in pages/articles
No <nuxt-content/>
this time…
The $content('articles').fetch()
will return all the content of our articles that's too much for what we need.
If you want to see what's there you can display it inside a <pre>
.
You can also use the /_content/articles
route, some more Nuxt magic there…
<template>
<div>
<pre>
{{ posts }}
</pre>
</div>
</template>
<script>
export default {
async asyncData ({ $content }) {
const posts = await $content('articles').fetch()
return { posts }
}
}
</script>
The Nuxt Content Module let us filter only the data we need.
export default {
async asyncData ({ $content }) {
const posts = await $content('articles')
.only(['path', 'title', 'createdAt', 'updatedAt'])
.fetch()
return { posts }
}
}
createdAt
and updatedAt
are added directly by Nuxt Content.
This data should be enough.
To display the data on our page, we'll loop over the posts
.
<ul class="PostsList">
<li v-for="post in posts" :key="post.slug" class="PostsList-item">
<nuxt-link class="MainLink" :to="post.path">
{{ post.title }} &mdash; <small>{{ post.createdAt.split('T')[0] }}</small>
</nuxt-link>
</li>
</ul>
You can see the result on the articles page
I'm writing a step by step guide, it would be cool if you can follow the steps without going to the list page, so let's add it in our articles/_slug.vue
component.
Nuxt Content Module has the surround
helper to fetch the previous and next article. You can read more about it on the Nuxt Content Module documentation site
import PrevNext from '~/components/PrevNext'
export default {
components: {
PrevNext
},
async asyncData ({ $content, params }) {
const post = await $content('articles', params.slug).fetch()
const surround = await $content('articles')
.sortBy('createdAt', 'asc')
.only(['title', 'path', 'createdAt'])
.surround(post.slug).fetch()
return { post, surround }
}
}
As you can see, I created a component, PrevNext.vue
.
This component will be added after the content of each article.
The template is now :
<template>
<div>
<nuxt-content :document="post" />
<PrevNext :surround="surround" />
</div>
</template>
The component is quite simple :
It takes a surround
prop, we check that the prev
or next
links are there to display the link.
<template>
<div class="PrevNext">
<nuxt-link v-if="surround[0]" :to="surround[0].path" class="PrevNext-prev">
<small>[Prev]</small><br>{{ surround[0].title }}
</nuxt-link>
<nuxt-link v-if="surround[1]" :to="surround[1].path" class="PrevNext-next">
<small>[Next]</small><br>{{ surround[1].title }}
</nuxt-link>
</div>
</template>
<script>
export default {
props: {
surround: {
type: Array,
default () { return [] }
}
}
}
</script>
We now have a website with an homepage, a blog with a list of articles and links to go to the previous or next article.
Let's add Forestry (a git-based headless CMS), to edit the content of our Nuxt site.