In today's JamStack world, pages are generated at build time, and you can deploy the static assets to any CDN network where it is served to users. However, one drawback of this approach is that there is no server-side rendering on the fly, and editors can not preview content before publishing it.
In this beginners tutorial, you'll learn how to integrate Nuxt Previews using Strapi as the backend.
As much as this domain is still under development, many solutions have been created to solve the problem, generating a preview deployment by rebuilding the entire website on a Test URL.
The first approach also has its challenges of longer rebuild time, giving way to the second approach, which takes advantage of those statically generated frameworks such as Nuxt.js that can hydrate into a full-blown single-page application.
We can then use JavaScript on the client-side to dynamically fetch the content from the CMS.
This feature is made possible in Nuxt.js > 2.13, and in this article, we will discuss how to set it up with the Strapi backend and implement Previews in a Nuxt.js single page application successfully.
Before you can jump into this content, you need to have a basic understanding of the following.
Before starting enabling and implementing previews in Nuxt.js, we need to install and set up Nuxt.js 2.13 or later in our local machine.
To install Nuxt.js, run through the following steps or skip if you already have it installed.
1npx create-nuxt-app nuxt-preview-demo
Follow through the instructions and select your preferred choice and make sure to choose SSR
and Static hosting
at rendering mode and deployment target, respectively.
Now that we have our Nuxt.js application installed successfully, we need to enable Nuxt preview.
Please create a new file in the plugins folder called preview.client.js
and paste it into the following code.
1// plugins/preview.client.js
2export default function ({ query, enablePreview }) {
3 if (query.preview) {
4 enablePreview()
5 }
6}
Next, add the newly created file to your nuxt.config.js
to enable the Next Preview plugin, open your nuxt.config.js
file and add this script to the plugins
array.
1export default {
2 //...
3
4 plugins: ['~/plugins/preview.client.js']
5
6 //...
7}
After configuring the preview successfully, if you visit any page of your Nuxt app with ?preview=true
query parameter, Nuxt will invoke the enablePreview()
function and disable any data from the server calls nuxtServerInit
, asyncData
, and fetch
methods on the client-side.
To test the preview mode, you need to run the following commands:
1npx nuxt generate
2
3npx nuxt start
The first command will generate a static SPA application, and the second command will start the development server.
If you look at the Network tab of your browser, you will see that Nuxt makes a call to the API even if in preview mode, so we can plug in Strapi API to generate data from our Strapi backend.
For pages that are not generated yet, if you call them with the ?preview=true
parameter, Nuxt will call the API first before showing the 404 error as the pages exist on the API but are not generated yet.
If you don't want it to redirect to the 404 pages in Preview mode, you can call the validate hook to handle such redirection.
1validate({ params, query }) {
2 if (query.preview) {
3 return true
4}
Strapi is an open-source content management system based on Node.js with exposed APIs for developers to design and deliver content faster. Strapi comes inbuilt with lots of great benefits and is also very popular among the JamStack community.
To learn more about Strapi and what it does, you can learn it from this article, as that is out of scope in this content.
To install and set up a Strapi application is as easy as just running the following commands. Inside the nuxt_preview_demo
folder, you created above, run the following commands.
1yarn create strapi-app nuxt-preview-api --quickstart
2
3cd nuxt-preview-api
4
5// If the server is not started by default
6yarn develop
We will have the Nuxt.js app and Strapi backend in the same folder. You can separate them if you want. The Strapi server should already be started, and open the Admin registration page on your default browser at localhost:13337/admin
.
Fill in your details and click on the "LET'S START" button. Strapi will create your account and will load the admin UI.
Next, we will build our first collection and fill in some dummy post data to display with our Nuxt Preview.
To create the collection, open the Admin panel and click on Collection Type Builder
on the left side of the page.
When the page loads, click on create new collection type
still at the left side of the page and fill in the following data.
Click on Continue
to create a new Post
collection. If you noticed, I have created other collections. That's the flexibility of Strapi.
Next, we need to fill the Post
collection with lots of Post data. You can achieve this in two ways: using the Admin UI and using Strapi generated API.
We will use the Admin UI for this tutorial, so follow the following steps to add Posts to the Post Collection you just created.
After clicking on Continue
, it will present you with another modal to select a field for your collection type.
Select Text
and fill in Title
at the name field. Click in Add another field
and repeat the process but select Long Text
for the description
field.
After adding all the required fields, click on Save
to save the collection and click on the Posts
name on the left side.
Next, click on Add new post
button to add a new post. Click on Save and Publish buttons, repeat the process to add five different posts content.
Before we can integrate the Strapi backend with the Nuxt preview, we need to configure and set up the Nuxt app we have already created at the beginning of this article.
We will start by creating pages and components to represent a fully developed website.
While trying to access the Post API, if you have any permission errors, you need to access the public user in the Strapi dashboard.
To allow access, click on Settings, then click on Roles and select Public, then check on Select All to assign all permissions to the Public user.
You should be able to access the Posts API after allowing permission successfully.
Open the /pages
folder and create the following pages:
1touch posts/index.vue
Paste in the following script in pages/posts/index.vue
file:
1<template>
2 <div>
3 <section>
4 <div class="container">
5 <h3 class="mt-5 text-center">Top Rated Posts</h3>
6 <p>A list of our highly rated posts.</p>
7 <Posts class="text-left" />
8 </div>
9 </section>
10 </div>
11</template>
12<script>
13export default {}
14</script>
Next, the Posts
component contains the logic of retrieving the posts from our Vuex State and presenting them to the browser.
1// /components/Posts.vue
2
3<template>
4 <div class="row row-cols-1 row-cols-md-3 g-4">
5 <Post v-for="post in posts" :key="post.id" :post="post" />
6 </div>
7</template>
8<script>
9import { mapState } from 'vuex'
10export default {
11 computed: {
12 ...mapState({
13 posts: (state) => {
14 return state.posts
15 },
16 }),
17 },
18}
19</script>
20<style></style>
Next, we have the Post
component, which represents a single Post and how to display it.
1<template>
2 <div class="col">
3 <div class="card h-100">
4 <div class="card-body">
5 <h5 class="card-title">{{ post.Title }}</h5>
6 <p class="card-text">
7 {{ post.description }}
8 </p>
9 <nuxt-link :to="`/posts/${post.id}`" class="btn btn-primary text-white"
10 >View Post</nuxt-link
11 >
12 </div>
13 </div>
14 </div>
15</template>
16<script>
17export default {
18 props: {
19 post: {
20 type: Object,
21 default: () => {},
22 },
23 },
24}
25</script>
26<style scoped>
27a {
28 color: inherit;
29}
30</style>
Next, we have our index.js
store file where the Post is fetched from, and in there, we connected to our Strapi backend to retrieve the posts data and store it in the posts
state.
1// store/index.js
2export const state = () => ({
3 posts: [],
4})
5export const mutations = {
6 STORE_POSTS(state, posts) {
7 state.posts = posts
8 },
9}
10export const actions = {
11 async nuxtServerInit({ commit }) {
12 const posts = await this.$axios
13 .$get('http://localhost:1337/posts')
14 .catch((e) => console.error(e))
15 commit('STORE_POSTS', posts)
16 },
17}
In this index.js
file, we use the nuxtServerInit
function, which is only available on the server-side, to fetch post content on the client-side.
That's the power of the Next Preview, and it's beneficial for generating static pages either for testing or hosting on a static hosting platform like Github Pages or Netlify.
The image above shows that when we added the ?preview=true
parameter, we can retrieve the Posts from our Strapi Backend using the nuxtServerInit
function.
So far, we have learned about Nuxt Preview and how we can integrate the Strapi backend with it to automatically generate content from the Server-side even when we are on the Client-side of Nuxt.js. We have learned how to set up and configure Strapi and Nuxt.js together to smooth the contents.
Keep coding!
This article is a guest post by Solomon Eseme. He wrote this blog post through the Write for the Community program. If you are passionate about everything Jamstack, Open-source or JavaScript and want to share, join the writer's guild!
Solomon Eseme a Software Engineer and Content Creator who is geared toward building high-performing and innovative products following best practices and industry standards. I also love writing about it at Mastering Backend.