DEV Community

Cover image for Story of how I speeded up a website for my Portfolio using Nuxt.js and Contentful

Posted on • Updated on


Story of how I speeded up a website for my Portfolio using Nuxt.js and Contentful

I'd like to share how I made my portfolio faster using Nuxt.js.
Let me give you some context for why I did it before getting down to the main topic.

​‎When the idea to create a website for my portfolio sprung to mind, I asked myself what my top priority should be.
The answer was the loading speed of the pages, because it gets under my skin when websites keep me waiting for their pages to be built, especially when the reception is terrible.
So I don't want it to happen on my portfolio.

Here are my main ideas to make my Portfolio faster.

  1. Calling APIs to fetch data only during the building process.
  2. Putting all the necessary data into JSON files in the building process in order to accomplish the first one.

APIs will not need to be called on the client-side by achieving these two.

Technologies I used for it

  1. Nuxt.js
  2. Netlify
  3. Contentful

Let me wrap your head around these technologies in case you are not familiar with them.


Nuxt.js is a framework for creating Vue.js applications. And it helps you build server-rendered Vue.js applications easily.
On top of that, it has the ability to generate static websites with the generate command.
It already sounds like this meets my needs, dosen't it?


Netlify offers hosting services for static websites.
And it provides you with an easy-to-use UI and intuitive workflows.
How you deploy a static site to Netlify may blow your mind.
Just push your code to Github.
That's it. It's so simple that even my grandmother can do it.


Contentful is a headless CMS.
Contentful makes posts you wrote accessible through APIs that allow you to fetch your content anywhere.
And you can write your posts in markdown.

Let's dive into more details.

As a refresher, here are what I wanna achieve.

  1. Calling APIs to fetch data on the server-side. This can be rephrased as all the data my portfolio needs completely has to be prepared before users visit my portfolio.
  2. Putting all the necessary data into JSON files in the building process in order to accomplish the first one.

The ideas sounded like a no-brainer but I realized I had no clue how to implement them when I sat in front of my laptop.
So I have googled a lot and came across Nuxt Modules which are called sequentially when booting Nuxt.
Nuxt.js waits for each module to be ready before moving on to the next step.
In addition to it, modules can easily register hooks for certain entry points.
As far as I read the documentation, calling APIs, fetching the content and putting it into JSON files can be done in a module during the building process.
If it's possible to do that, users no longer wait for the content to appear on a web browser so long.
And this was definitely a lifesaver for me.
So I decided to go with it.

Let's create JSON files in the module.
Here's the source code for the module.

const { createClient } = require('../plugins/contentful')
const { getConfigForKeys } = require('../lib/config.js')
const ctfConfig = getConfigForKeys([
const client = createClient()
import fs from 'fs'
module.exports = function postScraper(moduleOptions) {
  this.nuxt.hook('build:before', async ({ app }) => {
    const writeData = (path, data) => {
      return new Promise((resolve, reject) => {
        try {
          fs.writeFile(path, JSON.stringify(data), () => {
            resolve(`${path} Write Successful`)
        } catch (e) {
          console.error(`${path} Write Failed. ${e}`)
          reject(`${path} Write Failed. ${e}`)

    // fetch post data from contentful
      'content_type': ctfConfig.CTF_PAGE_TYPE_ID,
    }).then(posts => {
      const ids = []
      posts.items.forEach((post) => {
        writeData(`./static/posts/data/${}.json`, post)
      this.options.generate.routes = => `/news/${id}`)

As you can see, I just call the API as it's written in the documentation for Contentful and create JSON files for my blog post data.
You may or may not be aware that routes are generated with post ids because generating dynamic routes for individual blog posts is required.
To display the content, all you have to do is import the json files using the 'import' function.

async asyncData({ params }) {
    const post = await import(`~/static/posts/data/${}.json`)
    return {post: post.default}

This is all I did to make my portfolio faster.
What I have learnt through creating my portfolio is the power and flexibility of Nuxt.js.

I couldn't have done it without Nuxt modules. And I feel like I didn't get the most of this framework with this project.
Nuxt Modules can be useful to extend Nuxt.js's core functionality. I really wanna do a deep dive into Nuxt.js to leverage it to its fullest.
I'm sure that my solution is not flawless but this is the best one I can think of after a lot of research.

Thank you for reading.

Top comments (0)