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, 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 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: 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.
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.
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.
1 // plugins/preview.client.js
2 export 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 Nuxt Preview plugin. Open your nuxt.config.js
file and add this script to the plugins
array.
1 export 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:
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.
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.
1 validate({ params, query }) {
2 if (query.preview) {
3 return true
4 }
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.
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.
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.
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
, 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.
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.
You should be able to access the Posts API after allowing permission successfully.
/pages
folder and create touch posts/index.vue
file. 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>
13 export default {}
14 </script>
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>
9 import { mapState } from 'vuex'
10 export default {
11 computed: {
12 ...mapState({
13 posts: (state) => {
14 return state.posts
15 },
16 }),
17 },
18 }
19 </script>
20 <style></style>
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.attributes.title }}</h5>
6 <p class="card-text">
7 {{ post.attributes.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>
17 export default {
18 props: {
19 post: {
20 type: Object,
21 default: () => {},
22 },
23 },
24 }
25 </script>
26 <style scoped>
27 a {
28 color: inherit;
29 }
30 </style>
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
2 export const state = () => ({
3 posts: [],
4 })
5 export const mutations = {
6 STORE_POSTS(state, posts) {
7 state.posts = posts
8 },
9 }
10 export const actions = {
11 async nuxtServerInit({ commit }) {
12 const posts = await this.$axios
13 .$get('http://localhost:1337/api/posts')
14 .catch((e) => console.error(e))
15 commit('STORE_POSTS', posts.data)
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 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.
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. Click here to view the Github repo for the tutorial.
Mark Munyaka is a freelance web developer and writer who loves problem-solving and testing out web technologies. You can follow him on Twitter @McMunyaka