Vue Quick start guide

Estimated duration: 10 minutes

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

Blog site 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 Vue project to Prepr.

Create a simple Blog website with Vue.js and Prepr CMS

Create a new Vue project

The instructions below will guide you on how to create an empty Vue project for your blog app.

If you have an existing Vue project then you can skip this step.

  1. Open a terminal and execute the command below to create a new Vue project called prepr-vue.

    npm init vue@latest prepr-vue

    Go to the Router (SPA development) option and press the space bar to select it. This creates the same project structure used in this guide.

  2. When the project is successfully created, go to the prepr-vue folder, the root directory of the project, and start the project with the following commands in the terminal:

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

  4. Open your Vue project with your preferred code editor.

  5. Go to the src/views folder and replace the contents of the HomeView.vue file with the following code to display a single heading:

    ./src/views/HomeView.vue
    <template>
      <div>
        <h1>My blog site</h1>
      </div>
    </template>
  6. Replace the code in the App.vue file in the src folder with the code below to remove the Vue welcome and formatting from the page.

    ./src/App.vue
    <script setup>
    import { RouterView } from 'vue-router'
    </script>
     
    <template>
      <RouterView />
    </template>
  7. This project doesn't include any styling, so go to the src/assets folder and empty the main.css file to remove the existing styling.

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

Vue.js empty blog site

Install the 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 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 commands below in the terminal to install the Apollo client to execute GraphQL queries in a Vue project.

    npm install --save graphql graphql-tag @apollo/client
    npm install --save @vue/apollo-option @apollo/client
  2. Create a folder called services in the src folder. Then, create a file called apollo-client.js in this folder. Copy the following code to this file to import the Apollo client:

    ./src/services/apollo-client.js
    import { ApolloClient, createHttpLink, InMemoryCache } from '@apollo/client/core'
     
    // HTTP connection to the API
    const httpLink = createHttpLink({
      // You should use an absolute URL here
      uri: `https://graphql.prepr.io/${import.meta.env.VITE_PREPR_ACCESS_TOKEN}`,
    })
     
    // Cache implementation
    const cache = new InMemoryCache()
     
    // Create the apollo client
    const apolloClient = new ApolloClient({
      link: httpLink,
      cache,
    })
    export default apolloClient;
  3. Add the code below to the main.js in the src folder to import and create the Apollo Provider.

    ./src/main.js
    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router'
     
    // Import the Apollo provider and the apollo client
    import {createApolloProvider} from "@vue/apollo-option";
    import apolloClient from "@/services/apollo-client";
     
    // Initiate the Apollo provide
    const apolloProvider = createApolloProvider({
      defaultClient: apolloClient,
    })
     
    const app = createApp(App)
     
    app.use(router)
     
    //Include the Apollo Provider in the app
    app.use(apolloProvider)
     
    app.mount('#app')
  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
    VITE_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. Copy the GraphQL Production access token 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 command 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. Go to the src folder and create a queries directory. In here, create a file named get-posts.js.

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

    ./src/queries/get-posts.js
    import gql from 'graphql-tag'
     
    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 from the Post content item page in Prepr or the access token page.

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 blog 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 HomeView.vue file and add a script and HTML to execute the query and display the query results with the code below.
./src/views/HomeView.vue
<script>
import {GetPosts} from "@/queries/get-posts";
export default {
  apollo: {
    Posts: GetPosts
  },
  data() {
    return {
      Posts: ''
    }
  },
}
</script>
 
<template>
  <div>
    <h1>My blog site</h1>
 
    <ul v-if="Posts">
      <li v-for="post in Posts.items" :key="post._id">
        <router-link :to="post._slug">{{post.title}}</router-link>
      </li>
    </ul>
  </div>
</template>

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

Blog site end result

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, an empty page opens with the slug in the URL.

The instructions below show you how to create a route 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.

Create dynamic routing

  1. We added the Vue router as part of the installation, so adding routing is simple. Just update the index.js file in the router folder to add a route to the detailed blog post page as follows:

    ./src/router/index.js
    import { createRouter, createWebHistory } from 'vue-router'
    import HomeView from '../views/HomeView.vue'
     
    // import the detailed blog post page
    import PostView from "@/views/PostView.vue";
     
    const router = createRouter({
      history: createWebHistory(),
      routes: [
        {
          path: '/',
          name: 'home',
          component: HomeView
        },
     
        // Include routing to the detailed blog post page with the slug from the URL
        {
          path: '/:slug',
          name: 'post',
          component: PostView
        }
      ]
    })
     
    export default router

Continue with the next step to fetch the post details and display the page.

Fetch post details

Add another query to fetch a specific blog post by its slug and make this page visible when clicking the link for a post.

  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:

    ./src/queries/get-post-by-slug.js
    import gql from 'graphql-tag'
     
    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 post content.

The Blog 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 views folder and create a new file PostView.vue with the following code:

    ./src/views/PostView.vue
     
    <script>
    import {GetPostBySlug} from "@/queries/get-post-by-slug";
     
    export default {
      data() {
        return {
          Post: null,
        }
      },
      apollo: {
        Post: {
          query: GetPostBySlug,
          variables () {
            return {
              slug: this.$route.params.slug
            }
          }
        }
      },
    }
    </script>
     
    <template>
      <h1>{{Post.title}}</h1>
     
        <div class="my-10">
            <img
                :src="Post.cover.url"
                :alt="`Image for ${Post.title}`"
            />
        </div>
     
      <div :key="contentType._id" v-for="contentType in Post.content">
     
        <!-- Display images if they exist -->
        <div v-if="contentType.__typename === 'Assets'" class="my-10">
          <img
              v-if="contentType.items.length"
              :src="contentType.items[0]?.url"
              :alt="`Image for ${Post.title}`"
          />
        </div>
     
        <!--Display the text in HTML format -->
        <div
            v-if="contentType.__typename === 'Text'"
            v-html="contentType.body"
        ></div>
      </div>
    </template>

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

Blog post end result

All done

Congratulations! You have successfully connected a Vue 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