Building a JAMstack shop with Strapi 4, Nuxt 3, Snipcart - part 1
Published: 2021-12-01 12:37:44

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](https://pick-a-sick-wick.pixelhop.io/).

We've done our own designs for this little demo and they can be found [here](https://www.figma.com/file/mys8jJI7kb1gVhR43FqBWp/Pick-a-sick-wick?node-id=0%3A1), 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.

{% youtube AZZ6M1YXWlk %}

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:
* Strapi 4 👉 <a href="https://github.com/pixelhop/pick-a-sick-wick-frontend">https://github.com/pixelhop/pick-a-sick-wick-frontend</a>
* Nuxt 3 👉 <a href="https://github.com/pixelhop/pick-a-sick-wick-backend/">https://github.com/pixelhop/pick-a-sick-wick-backend/</a>

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:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ab9bd5axopwnovcarelg.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](http://localhost:1337/admin). You now just need to create your account.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c5g54cfyt3u40rs6cvvn.png)

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.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m2jnlrocxibpuotw34oh.png)

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


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/83h551kffsmt0srm2ij9.png)

Create the collection type like so:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kc8477ztkj7f16wbvl9.png)

*Note: I should have probably called this '`Products`'.*

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
    

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6a0vcuwd2ag3p7rtvovg.png)

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


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g6u43gn56lqfz5vbct8w.png)

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.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ks1xi2q5e0eu7mouo4kf.png)

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. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gv15qis2yuxtziqi54wf.png)

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


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6f797sgeg6ilepq87rge.png)

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


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0tytt57w85ytlm3by44r.png)

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.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cahwco7aqhutn7uip0r3.png)

You should now be able to go [http://localhost:1337/api/products](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 front-end 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](https://tailwindcss.com/) on every project; if you don't want to, you can just skip the next 2 steps.

```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](https://fonts.google.com/specimen/Playfair+Display) and [Source Sans Pro](https://fonts.google.com/specimen/Source+Sans+Pro).

Your code config file should look like this:

```jsx
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; go to your terminal and type:

```bash
npm run dev
```

*Note: make sure your node version is  > 14*

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/](http://localhost:3000/). Open it up and go check it out. You should have something like this:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jjicmtzylf4gag3mf2ay.png)

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 front-end you should see something beautiful like this.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bqwwfta7nu0pij9tldsu.png)

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`.

```jsx
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).

```html
<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 🎉


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a7cog87d9hbl60ac6hyh.png)

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](https://www.pixelhop.io/contact/) or [Twitter](https://twitter.com/pixelhopio). There's going to be a few more blog posts in this series, so feel free to [subscribe to our newsletter](https://www.getrevue.co/profile/pixelhop?via=twitter-profile-webview) 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.