How to Implement Previews with Nuxt Applications using a Strapi Backend
Tags: strapi, nuxt, javascript, headlesscms
Published: 2022-09-07 08:07:33

_In this step-by-step beginners tutorial, you'll learn how to integrate Nuxt Previews using Strapi as the backend to preview content before publishing it._

**Author: Mark Munyaka**

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.

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 the [Strapi Features Page](https://strapi.io/features), as that is out of scope in this content.

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](https://strapi.io/integrations/nuxtjs-cms) 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.

## Prerequisites
Before you can jump into this content, you need to have:
1. Basic knowledge of JavaScript,
2. Basic knowledge of Vue.js,
3. Basic knowledge of Nuxt.js, and
4. Basic understanding of Strapi - [get started here](https://strapi.io/documentation/developer-docs/latest/getting-started/introduction.html).

## Enabling Preview Mode in Nuxt (> v2.13)
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.

```bash
    npx create-nuxt-app nuxt-preview-demo
```

Follow through the instructions and select your preferred choice. 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 the following code.

```js
    // plugins/preview.client.js
    export default function ({ query, enablePreview }) {
      if (query.preview) {
        enablePreview()
      }
    }
```
Next, add the newly created file to your `nuxt.config.js` to enable the Nuxt Preview plugin. Open your `nuxt.config.js` file and add this script to the `plugins` array.

```js
    export default {
      //...
    
      plugins: ['~/plugins/preview.client.js']
    
      //...
    }
```

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:

```bash
    npx nuxt generate
    npx 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 it's in preview mode, so we can plug in Strapi API to generate data from our Strapi backend.

## Previewing New Pages
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.

```js
    validate({ params, query }) {
      if (query.preview) {
        return true
    }
```

## Scaffolding a Strapi App
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.

```bash
    yarn create strapi-app nuxt-preview-api --quickstart
    cd nuxt-preview-api
    # If the server is not started by default
    yarn 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. Open the Admin registration page on your default browser at `localhost:1337/admin`.

Fill in your details and click on the "LET'S START" button. Strapi will create your account and will load the admin UI.

## Build the Collection
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 `Content-Type Builder` on the left side of the page.

When the page loads, click on `Create new collection type` still on the left side of the page and fill in the following data.

![Create a collection type](https://paper-attachments.dropbox.com/s_36D12F9B210B7054A3770DE818D0110F6F2219FDF8223245FA15DA3D618F6605_1659373710249_create-a-collection-type.png)

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 field for collection type](https://paper-attachments.dropbox.com/s_36D12F9B210B7054A3770DE818D0110F6F2219FDF8223245FA15DA3D618F6605_1659373886836_select-field-for-collection-type.png)

Select `Text`, choose `Short text` for type and fill in `title` in the name field. Click in `Add another field` and repeat the process but name it `description` and select `Long Text` for the `description` field. Next add a `Rich text` field named `content`.

After adding all the required fields, click on `Save` to save the collection and wait for your Strapi app to restart. 

Click on the `Content Manager` on the left side. Select `Post` under the `COLLECTION TYPES`.

Next, click on `Create new entry` button to add a new post. Click on `Save and Publish` buttons, and repeat the process to add five different posts content.

## Integrating Strapi with Nuxt Preview
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** under the **Users-permissions** and check on **Select All** for the **Post** permissions and click on **Save**.

![Allowed Actions for User Permissions](https://paper-attachments.dropbox.com/s_36D12F9B210B7054A3770DE818D0110F6F2219FDF8223245FA15DA3D618F6605_1659375829112_allowed-actions-for-user-permissions.png)

You should be able to access the Posts API after allowing permission successfully.

## Creating Pages
1. Open the `/pages` folder and create `touch posts/index.vue` file. Paste in the following script in `pages/posts/index.vue` file:

```js
    <template>
      <div>
        <section>
          <div class="container">
            <h3 class="mt-5 text-center">Top Rated Posts</h3>
            <p>A list of our highly rated posts.</p>
            <Posts class="text-left" />
          </div>
        </section>
      </div>
    </template>
    <script>
    export default {}
    </script>
```
2. Next, the `Posts` component contains the logic of retrieving the posts from our Vuex State and presenting them to the browser.

```js
    // /components/Posts.vue
    
    <template>
      <div class="row row-cols-1 row-cols-md-3 g-4">
        <Post v-for="post in posts" :key="post.id" :post="post" />
      </div>
    </template>
    <script>
    import { mapState } from 'vuex'
    export default {
      computed: {
        ...mapState({
          posts: (state) => {
            return state.posts
          },
        }),
      },
    }
    </script>
    <style></style>
```
3. Next, we have the `Post` component, which represents a single Post and how to display it.

```js
    <template>
      <div class="col">
        <div class="card h-100">
          <div class="card-body">
            <h5 class="card-title">{{ post.attributes.title }}</h5>
            <p class="card-text">
              {{ post.attributes.description }}
            </p>
            <nuxt-link :to="`/posts/${post.id}`" class="btn btn-primary text-white"
              >View Post</nuxt-link
            >
          </div>
        </div>
      </div>
    </template>
    <script>
    export default {
      props: {
        post: {
          type: Object,
          default: () => {},
        },
      },
    }
    </script>
    <style scoped>
    a {
      color: inherit;
    }
    </style>
```
4. 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.

```js
    // store/index.js
    export const state = () => ({
      posts: [],
    })
    export const mutations = {
      STORE_POSTS(state, posts) {
        state.posts = posts
      },
    }
    export const actions = {
      async nuxtServerInit({ commit }) {
        const posts = await this.$axios
          .$get('http://localhost:1337/api/posts')
          .catch((e) => console.error(e))
        commit('STORE_POSTS', posts.data)
      },
    }
```
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 Nuxt Preview, and it's beneficial for generating static pages either for testing or hosting on a static hosting platform like Github Pages or Netlify.

![Posts read from Strapi API](https://paper-attachments.dropbox.com/s_4372DF3F8460C6F76FF896AAC9401756F5269CE6F0F6514F78180F7DAE93CCF7_1624102265629_pos.png)

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.

## Conclusion
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](https://strapi.io/integrations/nuxtjs-cms) together to smooth the contents. [Click here to view the Github repo for the tutorial](https://github.com/Marktawa/strapi-nuxt-preview).