Nuxt Quick start guide

Estimated duration: 10 minutes

This guide shows you how to connect Prepr to a Nuxt 3 project to get data from Prepr CMS. You'll learn how to make a simple blog with Nuxt and Prepr CMS. By the end of this guide, you'll have a working app that looks like the image below.

Nuxt QSG end result

If you want to skip ahead, try out the zero installation demo on Stackblitz (opens in a new tab) or clone the repository on GitHub (opens in a new tab) to run the demo locally.

Prerequisites

You need to have the following setup before you connect your Nuxt project to Prepr.

Create a simple Blog website with Nuxt and Prepr CMS

Create a new Nuxt project

The instructions below will guide you on how to create an empty Nuxt project for your blog app. If you have an existing Nuxt 3 project then you can skip this step.

  1. Open a terminal, go to your development projects folder and execute the following command to create a new Nuxt project called prepr-nuxt:

    npx nuxi init prepr-nuxt
  2. Choose npm for the package manager and choose defaults for the remaining options.

    Nuxt installation options

  3. When the project is successfully created, go to the prepr-nuxt folder, the root directory of the project, and run the project with the following commands in the terminal:

    cd prepr-nuxt
    npm run dev
  4. You should now be able to view your app on your localhost, for example, http://localhost:3000/.

  5. Open your Nuxt project with your preferred code editor.

  6. Update the app.vue file with the following code to display your blog:

    ./app.vue
    <template>
      <div>
        <h1>My blog site</h1>
      </div>
    </template>

You should now see something like the image below on your localhost.

Nuxt blog site - empty

Install the Nuxt Apollo client

The Apollo client is an integration tool that helps to retrieve CMS data with GraphQL. The instructions below show you how to install the Nuxt Apollo client (opens in a new tab) so that you can execute GraphQL queries to request data from the Prepr API.

  1. Stop the server you started in the above step (CTRL-C) and run the following command in the terminal:

    npm i -D @nuxtjs/apollo@next
  2. Create a folder called apollo in the root directory of your project. Then, create a file called prepr.ts in this folder. Copy the following code to this file to import the Apollo client:

    ./apollo/prepr.ts
    import { defineApolloClient } from "@nuxtjs/apollo";
     
    export default defineApolloClient({
      httpEndpoint: "https://graphql.prepr.io/graphql",
      defaultOptions: {},
      inMemoryCacheOptions: {},
      tokenName: "apollo:prepr.token",
      tokenStorage: "cookie",
      authType: "Bearer",
      authHeader: "Authorization",
      httpLinkOptions: {
        headers: {
          Authorization: `Bearer ${process.env.PREPR_ACCESS_TOKEN}`,
        },
      },
    });
  3. Next, open the nuxt.config.ts file and add the apollo module with the following code:

    ./nuxt.config.ts
    import { defineNuxtConfig } from 'nuxt/config'
     
    export default defineNuxtConfig({
      modules: ['@nuxtjs/apollo'],
      apollo: {
        clients: {
            prepr: './apollo/prepr.ts',
        },
      },
     
      // If deploying with Vercel, add config below
      build: {
        transpile: ["tslib"],
      },
    })
  4. We recommend using environment variables to store sensitive information like access tokens. To add environment variables, create a .env file in the root directory of your project and add the access token like this:

    ./.env
    PREPR_ACCESS_TOKEN=<YOUR-ACCESS-TOKEN>
  5. Replace the placeholder value <YOUR-ACCESS-TOKEN> with an access token from Prepr. Get an access token by logging into your Prepr account:
    a. Go to Settings → Access tokens to view all the access tokens.
    b. Click to open the GraphQL Production access token and use this value to only retrieve published content items on your site.

    access token

    Use the GraphQL Production access token to request published content items for your live app and use the GraphQL Preview token to make a preview of unpublished content items for your content editors.

  6. Execute the following commands to make sure that the Apollo client is installed correctly:

    npm run dev

If your app runs without errors, then the setup above was done correctly. The next step is to fetch content from Prepr using the installed Apollo client.

Fetch multiple blog posts

Now that your Apollo client is installed and connected to Prepr, fetch the blog posts from Prepr.

Add a GraphQL query

  1. Create a queries directory in the root directory of your project and create a file named get-posts.js.

  2. Add the following query to this file to retrieve all blog posts:

    ./queries/get-posts.js
    export const GetPosts = gql`
        query {
            Posts {
                items {
                    _id
                    _slug
                    title
                }
            }
        }
    `

    You can create and test GraphQL queries using the Apollo explorer (opens in a new tab) from Prepr. Open the API Explorer directly in Prepr from a specific Post content item or the access token details.

If you’re using preloaded demo data in your Prepr CMS environment as mentioned above in the Prerequisites section, you should have a few published posts as shown in the below image. The query will retrieve the ID, Slug, and Title of each blog post.

demo blog posts

In the next step, we'll fetch and process the query response.

Fetch data

Now that the query has been added, fetch the blog posts from Prepr and display them in the app.

  1. Open the app.vue file and replace the code with that below to display the data retrieved from the query:
./app.vue
<!-- ./app.vue -->
<template>
  <div>
    <h1>My blog site</h1>
    <ul>
 
      <!-- Loop through the blog posts array -->
      <li :data="post" v-for="(post, index) in posts" :key="post._id">
       <!-- Add a link for each slug and include the blog post slug in the directed path -->
       <nuxt-link :to="`/${post._slug}`">
          {{ post.title }}
        </nuxt-link>
      </li>
    </ul>
  </div>
 </template>
 
<script setup>
  //Import the query
  import { GetPosts } from "~/queries/get-posts";
 
  //Request the data from Prepr
  const { data } = await useAsyncQuery(GetPosts);
 
  //Map variable to all the blog posts from Prepr
  const posts = data.value.Posts.items;
 
 </script>

Now when you view the website on your localhost, you'll see something like the image below.

Nuxt blog site - blog post list

Fetch individual blog posts

Now you have the list of blog posts with links to them. When a visitor clicks a blog post link, your app should open a detailed post page automatically.

However, we haven't created the detailed page yet. Now, when you click the link, a new page opens with the slug in the URL, but a Page 404 error is displayed.

The instructions below show you how to set up the routing from the main page to the detailed page and how to fetch the blog post details based on the slug of the blog post that was clicked.

Set up dynamic routing

Nuxt reads all the .vue files inside a pages directory and automatically creates the router configuration, so setting up the routing is simple.

  1. To set up the automatic routing, create a pages folder.
  2. Move the app.vue file to the pages folder and rename it to index.vue.

Now, when you click a blog post link, a new page opens with the slug in the URL, but a Page 404 error is displayed.

Fetch blog post details

Follow the steps below to add another query to fetch a specific blog post by its slug and make this page visible when clicking the blog post link.

  1. Create a file called get-post-by-slug.js in the queries folder and add the following query to this file to query a specific blog post by its slug:
./queries/get-post-by-slug.js
export const GetPostBySlug = gql`
    query ($slug: String) {
        Post (slug: $slug) {
            _id
            title
            cover {
                url(width: 300, height: 250)
            }
            content {
                __typename
                ... on Text {
                    _id
                    body
                    text
                }
                ... on Assets {
                    items {
                        _id
                        url(width: 300, height: 250)
                    }
                }
            }
        }
    }
`

Now that the query is added, fetch the individual blog post by its slug. Fetch the title, cover image and the blog post content.

The post content is stored in a Dynamic content field. Check out the GraphQL docs for more details on how to fetch the data within this field.

  1. Open the pages folder and create a new file [slug].vue with the following code:
./pages/[slug].vue
./pages/[slug].vue
 
<template>
    <!-- Display title -->
    <h1 >
        {{ post.title }}
    </h1>
 
    <div class="my-10">
        <img :src="post.cover.url" />
    </div>
 
    <!-- Loop through the blog post content -->
    <div :key="contentType._id" v-for="contentType in post.content">
 
    <!-- Display images if they exist -->
      <div v-if="contentType.__typename === 'Assets'">
        <img
          v-if="contentType.items.length"
          :src="contentType.items[0]?.url"
        />
      </div>
 
      <!--Display the text in HTML format -->
      <div
        v-if="contentType.__typename === 'Text'"
        v-html="contentType.body"
      ></div>
    </div>
</template>
 
  <script setup>
    import { useRoute } from "vue-router";
    import {GetPostBySlug} from "~/queries/get-post-by-slug";
 
    // Use vue-router to determine the slug in the URL
    const route = useRoute();
    const slug = route.params.slug;
 
    // Retrieve a blog post by the slug
    const postQuery = await useAsyncQuery(GetPostBySlug, {
        "slug": slug
    });
 
    // Map to the retrieved blog post 
    const post = postQuery.data.value.Post;
 
   </script>

Now, when you view your site, you can click a blog post which will direct you to that specific blog post like in the image below.

Blog post detail page

All done

Congratulations! You have successfully connected a Nuxt project to Prepr for a simple Blog app.

Next steps

To learn more on how to expand your project, check out the following resources:

Was this article helpful?

We’d love to learn from your feedback