Enrich your new Nuxt 3 site with headless CMS content

By Ondrej PolesnyNov 3, 2021

We’ve been waiting for this ever since Vue 3 was released. Nuxt 3 is in public beta! What are the greatest improvements, and how can we use Nuxt 3 with a headless CMS?

In this article, I’ll introduce the most interesting new features of Nuxt 3, show how to fetch content from the Kontent by Kentico headless CMS, and provide you with a list of useful resources.

Nuxt 3 introduction

Nuxt used to be a static site generator for Vue.js. Now, they call it the hybrid Vue framework, as it does much more than just generate a few static files. It lets you implement a full-featured client/server app and decide on the rendering strategy for each page.

The new version has been available since October 12 and, among other features, brings these great improvements:

  • Vue 3 and Vite support
    Earlier this year, I implemented my first Vue 3 site on Vite and was amazed by the development speed. It brought the 0s delay when starting your project in the morning as well as the fast HMR. That enables you to work in VS Code in one window and, once you save the changes, have the site automatically update in the next.
    I mentioned that Nuxt lets you do client/server apps. Its new server engine called Nitro allows you to host the server bundle in the serverless environment or as an edge worker!
  • TypeScript support
    Nuxt 3 was completely rewritten with TypeScript, so you can work with fully typed components, pages, stores, and libraries.
  • App.vue component
    App.vue is the main component of Nuxt 3 and is useful for defining app-wide code like the initialization of SmartLink SDK for Web Spotlight.
  • Layouts with multiple slots
    As your HTML gets complicated, it’s not enough to have a single placeholder for child pages. Nuxt 3 allows you to define multiple slots in a single layout template:
<template>
  <slot name="nav"></slot>
  <hr />
  <slot />
</template>
  • Setup script
    Nuxt 3 allows you to use the following shorthand for the setup function we know from Vue 3 that improves the code readability. All defined variables are automatically available to the template.
<script setup>
  const data = {
    "page": {
      "title": "I'm a dynamic page"
    }
  }
</script>
  • <Head> component
    As almost every page needs to set its title, meta tags, OG tags, and so on, Nuxt 3 introduces the new Header component that lives within your page template and is injected into the HTML header of the final page. That makes adjusting the header as easy as outputting data on the template.
<template>
  <Head>
    <Title>{{ data.page.title }}</Title>
  </Head>
  ...
</template>
  • Server API routes and middleware
    Defining serverless functions in a dedicated API folder of your project quickly became a standard for leading Jamstack frameworks, and Nuxt is no exception. However, Nuxt 3 also allows you to define server middleware that can intercept all requests for logging or other purposes:
export default async (req, res) => {
  console.log(req)
}

Using Nuxt 3 with the Kontent headless CMS

Are you excited enough to try Nuxt 3 for yourself? Then I have two pieces of good news for you 🤓.

  • We’ve prepared a Kontent Nuxt3 module that hooks our JS SDK into the framework as a plugin and makes its deliveryClient available in all pages and components.
  • The Kontent Nuxt3 module works with the newest JS SDK that can be added into the client-side bundle as it’s lightweight (and currently in public beta like Nuxt).

How to install the Kontent Nuxt 3 module

First, let’s create the Nuxt app with the Nuxt 3 CLI:

npx nuxi init nuxt3-app
cd nuxt3-app
npm i

Then, install the Kontent Nuxt3 module:

npm i --save-dev kontent-nuxt3-module

Next, add the kontent-nuxt3-module as a build module in the nuxt.config.js configuration file:

// nuxt.config.js
...
buildModules: [
    'kontent-nuxt3-module'
],
...

And define the projectId (and other details of your project) in the same file under publicRuntimeConfig:

// nuxt.config.js
...
publicRuntimeConfig: {
  kontent: {
    projectId: process.env.KONTENT_PROJECT_ID,
    previewApiKey: process.env.KONTENT_PREVIEW_KEY,
    defaultQueryConfig: {
      usePreviewMode: true
  }
}
...

Note: You see I’m using .env file to store the app secrets, but you can also define them as string literals directly in the config file.

And you’re done! :-)

You can now use the deliveryClient and fluent API in your pages and components with nuxtApp:

// index.vue
async setup(){
  const kontent = useNuxtApp().$kontent
  ...
  const articles = await kontent.getItems<Article>()
    .type(Article_CODENAME)
    .orderByDescending("elements.date")
    .toPromise()
  ...
}

Kontent Nuxt3 sample app

It’s always easier to start with a template that has all the common features implemented. So if you want some inspiration, take a look at our Nuxt 3 sample app that features:

  • TypeScript
  • Custom layout
  • Dynamic routes based on content
  • Dynamic components based on content
  • Pinia store for data management

You’ll find it on GitHub.

Nuxt 3 resources

And as I promised at the beginning, you can find below a list of useful Nuxt 3 resources that helped me a lot with the implementation. I hope they’ll give you a head start too:

Conclusion

Nuxt 3 is still in beta, and you may stumble upon features that don’t work well or are not documented enough. But you can already enjoy the developer quality of life improvements and get a preview of what will soon be possible on production.

If you’re a Nuxt fan, join us on Discord and tell us what you like the most about Nuxt 3 🤗. 

Written by
Ondrej Polesny

As Developer Evangelist, I specialize in the impossible. When something is too complicated, requires too much effort, or is just simply not possible, just give me a few days and we will see :).

More articles from Ondrej

Subscribe to Kontent Newsletter

Stay in the loop. Get the hottest updates while they’re fresh!