✨ Strapi MCP is now Generally Available - let your agents manage your Strapi content ✨

App7 min read

E-commerce website with Nuxt.js, GraphQL, Strapi and Stripe (2/7)

March 29, 2022Updated on May 22, 2026

This tutorial is part of the « E-commerce website with Strapi, Nuxt.js, GraphQL and Stripe

Note: The source code is available on Github

Introduction

The installation script has just created an empty project. We will now start configuring it using the Content Types Builder, which allows you to create your content architecture using single or collection types. It is a core plugin of Strapi, only accessible when the application is in a development environment.

Goals

You will display a list of restaurants in your web app. The list is going to be managed through your Strapi API. At the end of this section, you should have a Homepage that looks like this:

Deliveroo Clone - Homepage

Step 1 - Create a new Restaurants collection type

A Strapi API includes, by default, the user Content Type. Right now, you need restaurants, so your new Content Type is going to be, as you already guessed, restaurant.

Strapi - Content-Type Builder

  1. Go to Plugins Content-Type Builder in the main navigation.
  2. Click on Create new collection type.
  3. Type Restaurant for the Display name, and click Continue.
  4. Click the Text field.
  5. Type name in the Name field.
  6. Switch to the Advanced Settings tab, and check the Required field and the Unique field settings.
  7. Click on Add another field.
  8. Choose the Media field.
  9. Type image under the Name field, and check the Single media option then click Finish.
  10. Finally, click Save and wait for Strapi to restart.

Well done! You created your first Content Type. The next step is to add some restaurants to your database.

Step 2 - Create new entries for the "Restaurant" collection type

Let's create a restaurant.

Strapi - Restaurant collection type

  1. Go to Content Manager
  2. Click on Collection types > Restaurant in the navigation.
  3. Click on Add new entry.
  4. In the Name field, type the name of your favorite local restaurant.
  5. In the Media field, import a new cover.
  6. Click Save, and Publish.

Create as many restaurants as you would like to see in your app. If you're lacking some inspiration, you can check Deliveroo 🙈 . Having the items in database is great. Being able to request them from the Strapi API is even better.

Step 3 - Set Roles & Permissions

When you were creating your restaurant Content Type, Strapi created, behind the scenes, a set of files located in api/restaurant. These files include the logic to expose a fully customizable CRUD API. The find route is available at http://localhost:1337/api/restaurants. Try to visit this URL and will be surprised to be blocked by a 403 forbidden error. This is actually totally normal, new Strapi APIs are secured by design. Don't worry, making this route accessible is actually super intuitive:

Strapi - Roles

We have just added some new restaurants. We now have enough content to consume. But first, we need to make sure that the content is publicly accessible through the API:

  1. Click on General > Settings at the bottom of the main navigation.
  2. Under Users & Permissions plugin, choose Roles.
  3. Click the Public role.
  4. Scroll down under Permissions.
  5. In the Permissions tab, find Restaurant and click on it.
  6. Click the checkboxes next to find and findOne.
  7. Finally, click Save.

Now go back to http://localhost:1337/api/restaurants. At this point, you should be able to see your list of restaurants. By default, the APIs generated with Strapi use REST conventions. In the next step, you will transform them into GraphQL.

Step 4 - Install GraphQL plugin

We will use the GraphQL plugin in our Strapi project to fetch and mutate your content. To use the plugin, run the command below.

    # Ctrl + C to close process
    cd backend
    npm run strapi install graphql

This plugin will add GraphQL functionality to your app. After the installation is complete:

  • Run npm run develop to start the development server.
  • Visit [http://localhost:1337/graphql](http://localhost:1337/graphql) to access GraphQL Playground.

The GraphQL Playground has an inbuilt text editor for you to enter your GraphQL commands, a play button for you to run your code and a screen to display the return values, error, or success message. Try the following query in your GraphQL Playground:

    query Restaurants {
      restaurants {
        data {
          id 
        }
      }
    }

You should see the restaurants. If you did, you are ready to go onto the next step.

Step 5 - Install Apollo

Apollo Client is a comprehensive state management library for JavaScript that enables you to manage both local and remote data with GraphQL. Use it to fetch, cache, and modify application data, all while automatically updating your UI. Let's install the packages we need. Open a new terminal:

    cd frontend
    npm install @nuxtjs/apollo graphql-tag

Now that we have the dependencies we need, let's import the @nuxtjs/apollo. Add the following module and configurations to your nuxt.config.js

    // nuxt.config.js
    const strapiBaseUri = process.env.API_URL || "http://localhost:1337";
    export default {
      // Modules: https://go.nuxtjs.dev/config-modules
      modules: ['@nuxtjs/apollo'],
    
      // Apollo: https://github.com/nuxt-community/apollo-module#usage
      apollo: {
        clientConfigs: {
          default: {
            httpEndpoint: `${strapiBaseUri}/graphql`,
          }
        }
      }
    }

It looks you are going to the right direction. In the next step, you will display these restaurants in your Nuxt.js app.

Step 6 - Creating a new page

Open pages/index.vue with your text editor, and copy/paste the following code

    // pages/index.vue
    <template>
      <div class="uk-container uk-container-xsmall">
        <h1 class="uk-heading-small">
          <span class="uk-invisible">Restaurants</span>
          <input
            v-model="query"
            class="uk-search-input"
            type="search"
            placeholder="Type to search"
          />
        </h1>
    
        <div
          v-for="restaurant in filteredList"
          :key="restaurant.id"
          class="
            uk-card uk-card-default uk-grid-collapse uk-child-width-1-2 uk-margin
          "
          uk-grid
        >
          <figure class="uk-flex-last uk-card-media-right uk-cover-container">
            <img
              :src="getStrapiMedia(restaurant.attributes.image.data.attributes.url)"
              :alt="restaurant.attributes.image.data.attributes.alternativeText"
              uk-cover
            />
          </figure>
          <div>
            <div class="uk-card-body uk-card-small">
              <h2 class="uk-card-title">{{ restaurant.attributes.name }}</h2>
              <NuxtLink
                class="uk-button uk-button-text"
                :to="{ name: 'restaurants-id', params: { id: restaurant.id } }"
              >
                See dishes
              </NuxtLink>
            </div>
          </div>
        </div>
        <div v-if="filteredList.length == 0" class="uk-heading-small">
          <p>No restaurants found</p>
        </div>
      </div>
    </template>
    
    <script>
    import { getStrapiMedia } from '@/utils/media'
    import restaurantsQuery from '@/apollo/queries/restaurants'
    export default {
      data() {
        return {
          restaurants: [],
          query: '',
        }
      },
      apollo: {
        restaurants: {
          prefetch: true,
          query: restaurantsQuery,
        },
      },
      computed: {
        filteredList() {
          if (!this.restaurants?.data) return []
          return this.restaurants?.data?.filter((restaurant) => {
            return restaurant.attributes.name
              .toLowerCase()
              .includes(this.query.toLowerCase())
          })
        },
      },
      methods: {
        getStrapiMedia,
      },
    }
    </script>

We’re using UIkit a lightweight and modular front-end framework for developing fast and powerful web interfaces, it contains a set of layout components like Card and Grid that make it easy to style your website. Let’s run the following command to install uikit:

    npm install uikit

To import UIkit, create a new plugins/uikit.js and copy/paste the following code.

    // plugins/uikit.js
    import Vue from 'vue'
    
    import UIkit from 'uikit/dist/js/uikit-core'
    import Icons from 'uikit/dist/js/uikit-icons'
    
    UIkit.use(Icons)
    UIkit.container = '#__nuxt'
    
    Vue.prototype.$uikit = UIkit

Reference the new UIkit in your nuxt.config.js like this.

    // nuxt.config.js
    export default {
      // Global CSS: https://go.nuxtjs.dev/config-css
      css: [
        "uikit/dist/css/uikit.min.css",
        "uikit/dist/css/uikit.css",
      ],
    
      // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
      plugins: [
        { src: '~/plugins/uikit.js', ssr: false }
      ]
    }

We can load GraphQL queries over .gql files. This enable queries to be separated from logic. Let’s create a new graphql template. Create a new file apollo/queries/restaurants.gql, and copy/paste the following code:

    query Restaurants {
      restaurants {
        data {
          id
          attributes {
            name
            image {
              data {
                attributes {
                  url
                  alternativeText
                }
              }
            }
          }
        }
      }
    }

Finally, let’s create a new folder utils inside the frontend directory, where we will put our commons helpers. Then create a new empty file media.js in the utils directory, media.js will provide us with a tiny helper to obtain images absolute URL. Let’s add our getStrapiMedia util to the utils/media.js file:

    // utils/media.js
    export function getStrapiMedia(url) {
      // Check if URL is a local path
      if (url.startsWith("/")) {
        // Prepend Strapi address
        return `${process.env.strapiBaseUri}${url}`;
      }
      // Otherwise return full URL
      return url;
    }

And create a new environment variable in your nuxt.config.js:

    // nuxt.config.js
    export default {
      // ENV: https://nuxtjs.org/docs/configuration-glossary/configuration-env
      env: {
        strapiBaseUri,
      },
    }

This will append our Strapi Base URI to the image source. Great! After completing the homepage:

  • Run npm run dev to start the development server.
  • Visit http://localhost:3000 to view your application.

Conclusion

Well done! You can now see your restaurants! 🍔 In the next section, you will learn how to display the list of dishes.

Pierre BurgyChief Executive Officer

Pierre created Strapi with Aurélien and Jim back in 2015. He's a strong believer in open-source, remote and people-first organizations. You can also find him regularly windsurfing or mountain-biking!

App·26 min read

Build a To-Do App with Strapi GraphQL Plugin and Flutter

In this tutorial, we will set up a GraphQL endpoint in a Strapi backend along with Flutter, a powerful opensource UI...

·August 30, 2023
App·16 min read

How to build a To-do App using Next.js and Strapi

How to build a Todo App using Next.js and Strapi Updated July 2023 In this article, we will learn how to use , and to...

·August 29, 2023
How to setup Amazon S3 Upload Provider Plugin for your Strapi App
AppBeginner·14 min read

How to Set up Amazon S3 Upload Provider Plugin for Your Strapi App

Learn how to set up the Amazon S3 Upload Provider Plugin for your Strapi App to work with an Amazon S3 storage bucket.

·July 3, 2023