Our Writing

Building a JAMstack shop with Strapi 4, Nuxt 3, Snipcart - part 1.

Gemma

Gemma /

This series of articles will show you how to build a JAMStack e-commerce shop using the latest tech; Nuxt 3 for the front-end, Strapi 4 for the CMS backend, and Snipcart to power the e-commerce.

Here's a link to the shop that we've built, if you follow this series of blog posts this is what you'll also end up with Pick a Sick Wick.

We've done our own designs for this little demo and they can be found here, so as we take you through how to build this out, I will follow a design that we've done for this series.

Watch the video or follow along below.

If you are the kind of person that likes to dive straight into code, we have created example repositories for both the Nuxt and Strapi parts:

I can't tell you how excited we've been, waiting in anticipation for Nuxt 3 and Strapi 4 to come out, and now they're here, and we're ready to get our hands dirty and start using them straight away. I've always wanted to build an online candle shop, so I thought now's the time, and I can show you how to do it too, so let us go and Pick a Sick Wick.

Project setup with Strapi and Nuxt

If you're the sort of person that likes to get straight into the code, then look no further; you can find the repos:

  • The front-end is using Nuxt 3, and the repo is here
  • The backend is using Strapi, and the repo can be found here

Feel free to pull it down and dig in.

Here's a step by step guide on how to build your own shop, so let's stop waffling and let's get building.

Just to give you a little heads up, our folder structure is going to look something like this:

Screenshot 2021-11-26 at 15.47.02.png

Let's just create our folder and go into it, open up your terminal and run:

BASH
take pick-a-wick

Strapi 4

Now we're going to get Strapi 4 setup to create the data ready to be pulled through the Nuxt 3 front-end.

BASH
npx create-strapi-app@beta backend --quickstart

Let the terminal do the hard work for you, sit back have a sip of coffee and a biscuit. Once it's finished, a new tab will open in your browser here: http://localhost:1337/admin. You now just need to create your account.

Tada! How easy was that?! Here's your Strapi Dashboard; if you're used to using Strapi 3, you'll see some differences here; if you ask me (and I know you're not, but here's my opinion anyway 🙈), I think it looks a lot cleaner, lighter and nicer.

Let's jump in and start creating the architecture of the products by creating a collection type.

Create the collection type like so:

Then add in the fields you require; for now, we'll add in these fields :

  • Title - Text field
  • Description - Text field
  • Image - Media field
  • Prices - Number field

Now that you've added in your fields, make sure you save the collection. Your fields should look something like this:

Click the button in the top left and go to Content Manager > Products and, let's add in some new entries; for me, I'm going to be adding in some candles.

Click Add new entry and fill out all the data; once you're done, click Save and Publish and add in a couple more. We have added in some silly joke names because we thought it was funny haha.

Wahoooo, now you should have a list of products 🕯🛍 !!

Now, all we need to do is make the product content public to fetch it from the frontend. To do this go to General > Settings > Users & Permission Plugin > Roles.

Click Public and open out the Product accordion and check to find and findone; finally, just save it, and your products data should now be public.

You should now be able to go http://localhost:1337/api/products and see a JSON blob with all your products in.

Nuxt 3

Wahoooo, now you're backend is all set up and ready to party; let's move on to the frontend and set up Nuxt 3. Open up terminal and type:

BASH
// pick-a-wick is the name of the directory the Nuxt installation will save into
npx nuxi init frontend

Now just head into that directory:

BASH
cd frontend

Install all of the dependencies:

BASH
npm install

If you're anything like us, we use Taliwind on every project, and this one is no different. So let's get that setup:

BASH
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest

Generate the Tailwind and Postcss config files

BASH
npx tailwindcss init -p

Time to open up your code in your chosen editor; for me, it's VSCode; just do that from the command line, like so:

BASH
code .

You will need to add some config to your nuxt.config.ts file, lets also add in the Google fonts whilst we are here. The ones we're using are Playfair Display and Source Sans Pro.

Your code config file should look like this:

app/src/nuxt.config.js
JAVASCRIPT
import { defineNuxtConfig } from 'nuxt3'

export default defineNuxtConfig({
  // Add entry css file
  css: ['tailwindcss/tailwind.css'],
  build: {
    postcss: {
      // add Postcss options
      postcssOptions: require('./postcss.config.js'),
    },
  },
  meta: {
    link: [
      { rel: 'preconnect', href: 'https://fonts.googleapis.com' },
      { rel: 'preconnect', href: 'https://fonts.gstatic.com' },
      { href: 'https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700;800;900&family=Source+Sans+Pro:wght@300;400;600;700;900&display=swap', rel: 'stylesheet' }
    ]
  }

})

Finally, let's get it up and running, one thing to note is your Node version needs to be 14 or higher. So, go to your terminal and type:

BASH
npm run dev

Wahoooo!! How easy was that!? Your Nuxt site should now be up and running, if you've nothing else running, it will probably be on port 3000, and the URL will be http://localhost:3000/. Open it up and go check it out. You should have something like this:

To check you've got Tailwind up and running okay, you can head back over to the code base and into the app.vue file and add a Tailwind class around

HTML
<template>
  <div>
    <h1 class="text-red-500 bg-green-200">This is a title</h1>
  </div>
</template>

On the frontend you should see something beautiful like this.

We've done some designs for this project, so I'll be following them whilst going through this tutorial. Before we go on let's add in some default colours and fonts into tailwind.config.js.

JAVASCRIPT
module.exports = {
  purge: [
    "./components/**/*.{vue,js}",
    "./layouts/**/*.vue",
    "./pages/**/*.vue",
    "./plugins/**/*.{js,ts}",
    "./nuxt.config.{js,ts}",
    "./app.vue",
  ],
  mode: 'jit',
  darkMode: false, // or 'media' or 'class'
  theme: {
    extend: {
      colors: {
        'brand-grey': {
          300: '#828282',
          DEFAULT: '#898989',
          500: '#B5B5B5',
          600: '#5E5E5E',
          800: '#383838',
        },
        'brand-beige': {
          100: '#E5E5E5',
          200: '#E3D9CD',
          300: '#EAE5E0',
          DEFAULT: '#E9BA9E',
        },
        'brand-brown-500': '#4E3924',
        'brand-orange': '#FF6721',
      },
      fontFamily: {
        'heading': ['Playfair Display', 'serif'],
        'body': ['Source Sans Pro'],
      }
    },

  },
  variants: {
    extend: {},
  },
  plugins: [
    require('@tailwindcss/aspect-ratio'),
  ],
}

Right, we're making headway now; if you're still with me, thank you, I'm pleased I've not bored you too much so far, hehe, and if you're not, I totally understand. Time to get the products from Strapi coming out in the front-end. Buckle up this is going to be fun. In the root folder, create a new directory called pages within that create a page called index.vue. This is going to be the new homepage. We're going to tidy it up and split everything into its own components in the blog post, but for the time being, we just want to try and get the data back from Strapi. First, we want to fetch all the data, then we want to loop over all the products and put the data out onto the homepage using Nuxt 3, this is really easy to do and the code is fetch the data is only 1 line, sexy if you ask me. useFetch is a global helper function provided by Nuxt 3 that will load the data for the page server side, or during static generation of the page.

<script setup> allows you to use the more streamline syntax to create your Vue components (e.g. you don't have to register components or create data objects).

JAVASCRIPT
<template>
  <div>
    <div v-for="product in products.data" :key="product.id">
      <nuxt-link :to="`/products/${product.id}`">
        <h1 class="font-bold">{{ product.attributes.Title }}</h1>
        {{ product.attributes.Description }}
      </nuxt-link>
    </div>
  </div>
</template>

<script setup>
  const { data: products } = await useFetch('http://localhost:1337/api/products')
</script>

To get the index page showing we just need to edit our app.vue file to look like this. This is the route file that kicks everything off. Nuxt page is a component that is added by Nuxt and provides a location for your Nuxt pages to appear.

HTML
<template>
  <NuxtPage/>
</template>

If you check your browser you should have the title and description of your products wooooo 🎉

Wooo! Fingers crossed that's all working for you but if you have any questions feel free to get in touch and ask any more questions via our website or Twitter. There's going to be a few more blog posts in this series, so feel free to subscribe to our newsletter to find when they've been released.

Thank you for reading and next we will be building out the design, and all of the components etc. Once we've got it working we will then integrate Snipcart. And it won't be too long until you can have your own shop.

Subscribe.

Like what you’re reading? Sign up to recieve our updates straight to your inbox. No spam, unsubscribe anytime!

Related posts.

Creating an internationalised site with Strapi and Nuxt

We were really excited when Strapi released a new update a few weeks ago that included internationalisation! This post will show you the basics of creating an internationalised site using Strapi and Nuxt.

Read more

Dynamic social images with Nuxt, Cloud Functions and Cloudinary

Every little helps when trying to get your content noticed on social media, and having an eye-catching sharing image could be the difference between getting someone passing you by or someone clicking through. This post will guide you by creating dynamic social sharing images unique to each page/post using Firebase cloud functions, Cloudinary and Nuxt.

Read more