How to use asyncData to Integrate Contentful into Nuxt
A new foundation to my client work
Yesterday we launched a simple web app for Motown which surfaces daily facts from the storied label’s history. I’ve already shared a few technical solutions from this project in the midst of development including adding Apple Music search to Contentful, building a simple calendar with CSS grid, and recreating the Instagram auto-play UX. Now that the project is live, I’d like to quickly explain how we integrated Contentful into our Nuxt.js app in the first place.
Contentful, for the unaware, is a content infrastructure which integrates nicely into modern frameworks like Nuxt. We’re using it on the Motown project to manage all of the stories, artists, and songs connected to the label’s history. In order to keep this blog brief, I’m assuming you already have some data in Contentful. If not, simply check out their excellent Getting Started article, create some data, and return here.
The first thing we’ll do is create a new Nuxt project so create an empty directory for your project and change to that directory.
mkdir motown
cd motown
Then create a package.json
file to keep track of your project’s dependencies.
{
"name": "motown",
"scripts": {
"dev": "nuxt"
}
}
Finally, add nuxt
to your project.
npm install --save nuxt
While we’re at it, let’s install the Javascript SDK for contentful and the @nuxtjs/dotenv module to manage our local (Contentful) environment variables.
npm install --save contentful @nuxtjs/dotenv
We’ll then want to create a .env
file in our project’s root directory and specify variables for your Contentful space id and content delivery api access token. Both of these can be found in your Contentful account under Settings > API keys.
CONTENTFUL_SPACE_ID=123
CONTENTFUL_ACCESS_TOKEN=abc
Now in order to use these variables within our project, we’ll need to include the module into our Nuxt project’s nuxt.config.js
configuration file. This file should also be created in your project’s root directory.
require('dotenv').config()export default{
env: {
CONTENTFUL_SPACE_ID: process.env.CONTENTFUL_SPACE_ID,
CONTENTFUL_ACCESS_TOKEN: process.env.CONTENTFUL_ACCESS_TOKEN
}
}
Sweet, now your project has the ability to access your published Contentful data. We’ll now create a Nuxt plugin to initialize a Contentful client based on our space id and access token. Create a new directory called plugins
in your root directory and add a file called contentful.js
. Now, let’s export an API client within this file.
const contentful = require('contentful')const config = {
space: process.env.CONTENTFUL_SPACE_ID,
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN
}const client = contentful.createClient(config)export default client
Alright, we’re close now. The final step is to create a page within your Nuxt project which will use this plugin to get your data from Contentful. Create another directory in your project’s root folder called pages
and create a file called index.vue
within it. Nuxt pages are Vue components which allow you to declare your HTML, CSS, and Javascript all in the same place. Let’s add a simple placeholder template for now.
<template>
<section>
<h1>Contentful + Nuxt = 🔥</h1>
</section>
</template>
Right below that, we can declare the <script>
necessary to import the Contentful plugin we created. With this plugin imported, we can then use the asyncData method to get our entries from Contentful. This method is rad because it fetches your data on the server or client before the page component is rendered. Nuxt will also use it’s baked in loading component to inform your users of the loading progress.
<script>
import contentful from '~/plugins/contentful.js'export default{
asyncData ({ params }) {
return contentful.getEntries({ 'content_type': 'story' })
.then(result => { stories: result.items })
}
}
</script>
We use the Contentful client to get all entries of the content type story and then return the found items within an object which Nuxt.js will merge into our page component’s data. We now have access to our Contentful data through our page. For the sake of this exercise, let’s simply loop over the items and display them as paragraphs in our HTML.
<template>
<section>
<p v-for="story in stories">
{ story.fields.headline }
</p>
</section>
</template>
Now that you have some Contentful managed data coursing through your application, it’s up to you to decide what might come next. I look forward to seeing what you might build with these incredible technologies.