In this article, we zoom in on two of my favourite features of Nuxt content module. We will use Vue components inside markdown file without using any external dependency and complex configurations, and fetch .json
data into Nuxt page without using any API setup. Apart from fetching and displaying content, content module allows us to write content in several different formats.
To demonstrate these features, we'll take a look at sorting-activity component, which is a single file component. And we're going to provide data for this component using Nuxt content module. Sorting-activity component can be used in .vue
files and .md
files as well.
Before we dive in, here is the demo and the Github repo of the sample project.
In eLearning, sorting activity is classified as an interaction that is used to check users' knowledge on a particular topic by asking them to categorise (depending on the differences or similarities) set of cards into their respective groups.
The sorting activity you see in the demo above, is based on such an interaction provided by a popular eLearning authoring tool called Articulate Rise.
Let's see how this component works.
Sorting-activity component requires two props, items
and categories
, where items are draggable cards and categories are droppable targets.
We will write, fetch and provide items
and categories
as props
using Nuxt content module using:
Here's how the component tag looks like:
// See component at, components/global/GsapSortable.vue
<gsap-sortable :categories="categories" :items="items"></gsap-sortable>
Let's see both features one by one.
Imagine if you have to add interactive quiz - or activity in this case - to supplement your article content that you've written in markdown!
Say you all your articles are sitting under, /content/articles
directory.
| content
--|articles
----|popular-detectives.md
----|superhero-post-1.md
----|superhero-post-2.md
----|...
For each article, you want to populate the activity with relevant data to match the topic of your article.
With Nuxt modules, we can simply put our components in /components/global/
directory and they will be available for use inside markdown file. This is where we will keep <gsap-sortable>
component.
But you may wonder, how can we provide contextual props data for each activity?
Well, with the magic of frontmatter, we can declare items
and category
data as yaml
, like below:
// /content/activities/superhero-acitivty.md
---
title: Superhero Family
categories:
- label: Marvel Universe
name: marvel
list: []
- label: DC Comics
name: dc-comics
list: []
items:
- name: Superman
category: dc-comics
- name: The Hulk
category: marvel
- name: Green Lantern
category: dc-comics
- name: Iron Man
category: marvel
- name: The Flash
category: dc-comics
---
And then bind both items
and categories
variables as props with Vue component that is added in the markdown file.
// /content/activities/superhero-acitivty.md
---
title: Superhero Family
---
<gsap-sortable :categories="categories" :items="items"></gsap-sortable>
And there you have it!
If you have done this manually, before we had Content module, then you'd know how many dependencies and configurations it took to achive the same result as above.
You'd have used:
I had all four of the above for my own blog, but now, the amazing Content module takes care of all of that for us!
Take a look at the Articles page of the demo to see this in action.
Now let's say we want to create a collection of activities that users can interact with back to back.
We can use first option, and define acitivty data in yaml
. But if we only need the data, that we would otherwise fetch via an API, then we can certainly use .json
to write our data instead.
To do so, we can store all our activity data as .json
under the /content
folder.
| content
--|activities
----|activity-1.json
----|activity-2.json
----|activity-3.json
----|...
Then, fetch the data using $content
into Nuxt page.
export default {
async asyncData({ $content, params }) {
const activity = await $content("activities", params.slug).fetch();
return { activity };
},
};
Remember, no body
is generated when we fetch .json
data using Nuxt content module. We get an object with default keys, such as, dir
, slug
, path
, extension
along with the data that's defined in our .json
file, i.e. items
and categories
...
{
"dir": "/activities",
"slug": "sortable-activity-1,
"path": "/activities/sortable-activity-1",
"extension": ".json",
"items": ...,
"categories": ...
}
...which we can provide as props to be used with <gsap-sortable>
in the template area of the page component.
<gsap-sortable
:categories="activity.categories"
:items="activity.items"
></<gsap-sortable>
Take a look at the Learning Acitivties page of the demo to see this in action.
This demostration of Nuxt content module uses only handful of options, but are very impactful and provides an amazing developer experience. Make sure you read Debbie's article on the same topic to see all features in action.
In case you missed it, don't forget to check this printable PDF of Content Module cheatsheet that I published last month.
For more demos and articles on Nuxt, you can follow me on twitter at @KrutiePatel and subscribe to Nuxt Newsletter.