How to Build an E-commerce Website with Nuxt

Lately i had the chance to build a tailor-made e-commerce for a client, totally in JAMstack philosophy. This involves using a Static Site Generator (SSG), like Nuxt.js with Vue.js, paired with a headless CMS, in this case Prismic, and then hosted on Netlify (a CDN).
What about the shop/payment logic? Well, for that there is one hell of tool, called Snipcart. It handles all the nasty things very well, lighten the burden of the work.

I want to share my method and my experience with you, so feel free to give me advices about it.
Let’s unravel!

Step 1: Get on Prismic and Snipcart

Can’t do very much without an account on these platform right? Head over their website and create one (https://prismic.io/ , https://snipcart.com/).
Note: if the content or the cart will be managed by your client, be sure to create the accounts with his information, not yours.

Step 2: Setup you Nuxt project

Launch the create-nuxt-app and do the initial setup. If you are doing this in an already created project, be sure to upgrade Nuxt to at least version 2.12. This is because they added a bunch of new features that are worthy.

Step 3: Implementing Snipcart

Nothing more simple: Snipcart provides 3 lines of code (yup) to add to your code.
In the nuxt layout you want to enable the cart, past this two lines of code after the `` wrapper:

<div hidden id=”snipcart” data-api-key=”{public-key}”></div>
<script src=”https://cdn.snipcart.com/themes/v3.0.11/default/snipcart.js"></script>

The order is important, otherwise later personalization will have no effect.
The {public-key}has to be replaced with your key. You can retrieve it on your Snipcart account, under “API KEYS” in the menu on the right. Live and Testing keys are different, be sure to swap the key when the site will go live! Now, head over nuxt.config.js in order to add the css file for Snipcart:

link: [
{ rel: 'stylesheet', href: 'https://cdn.snipcart.com/themes/v3.0.11/default/snipcart.css' },
]

Aaaand done! Note: if you are using nuxt-i18n you’ll need to add parsePages: falsein its settings.
Note2: these snippet are available on your Snipcart account, always at the newest version, be sure to check!

Understanding Snipcart

You don’t have to manually add products on the platform (you do this on Prismic). When the product is added to a cart and bought for the first time, the product will be added to the catalog, from there you can set a stock limit, view the buyers, and many other things.
So, how can i add a product to the cart? Easy, you add a few classes to a buttoninside your product page:

<button class=”default-button cart-button extra-mt snipcart-add-item”
:data-item-id=”product.uid”
:data-item-price=”product.data.price”
:data-item-url=”$route.path”
:data-item-description=”product.data.description”
:data-item-image=”product.data.thumbnail.url”
:data-item-name=”product.data.title”
data-item-custom1-name=”Size”
:data-item-custom1-options=”size.size”
data-item-custom2-name=”Color”
:data-item-custom2-options=”color.color”>

Add to cart

</button>

This is straight out of my project. The class snipcart-add-itemwill add the product to the cart, grabbing all the information from the data fields.

The layout that Snipcart provides for the cart and the checkout page is very nice, but of course you’ll want to modify that to match the style of the site.
There are 2 ways to customize the cart’s view:

  • CSS Overrides: Just add a new css file where you can override the classes used on the checkout page. Just inspect the elements with the devtools and you’re good to go!
  • Custom Components: You can override the default components used by Snipcart and integrating your own, changing drastically the feel and the behavior of the cart. A bit more complex but surely satisfying.

I recommend you to visit the documentation (https://docs.snipcart.com/v3/), it’s very well written and they show you a bunch of cool features in order to manage the cart onsite.

Step 4: Implementing Prismic

Prismic offers various ways for installing their tools, depending on the language/framework. We are using Nuxt, so:

npm install @nuxtjs/prismic

In nuxt.config.js:

modules: [
   '@nuxtjs/prismic',
   '@/modules/static',
   '@/modules/crawler',
],

prismic: {
   endpoint: 'https://{your-repo}.cdn.prismic.io/api/v2',
   linkResolver: '@/plugins/link-resolver',
   htmlSerializer: '@/plugins/html-serializer',
}

generate: {
   fallback: '404.html',
}

Mmm, let’s see:

Modules static and crawler are newly added features requiring Nuxt >2.12. What are they? They will handle the dynamic generation of your routes. You will no longer have to write server logic in nuxt.config.js in order to retrieve all the routes server side. This is, frankly, pretty awesome. The crawler will seek all the links generated on deploy phase and generate the related routes in complete autonomy.

And again:endpoint: this is the link to your Prismic repo.

linkResolver and htmlSerializer: JS files needed to convert links and templating. (useful on blogs, or in projects where the content created on Prismic are articles with Rich Texts or other complex stuff; in my case, i don’t need them).

Fetching data from Prismic

Now that everything is set, we’re gonna see some new feature introduced with Nuxt 2.12.

For Server Side Rendering, in order to retrieve data to make all the static page, asyncData()or nuxtServerInitwere used.
But now we can use the new fetch(). What are the main differences?

  • asyncData() does not have access to this, while fetch does.
  • It can set data props directly.
  • It grants access to some options and objects, like $fetchState.pending , to check if the component is still loading data from the API (and showing a spinner, instead)
  • Allow faster page transitions, instead asyncData() would wait for the response in order to render the page.
  • BE CAREFUL: If you need to set dynamically head() meta (for example for a product page), you’ll need to use asyncData() because it will get the data before head() is called. In my case I made a tiny api call in asyncData() only for title and description, the rest is retrieved by fetch() .

More here: https://nuxtjs.org/api/pages-fetch/

That said, let’s see some code fetching from Prismic API:

<script>
  export default {
    async fetch() {
      try{
        const query = await this.$prismic.api.query(this.$prismic.predicates.at('document.type','category'), { orderings : '[my.category.position]' })
        this.docs = query.results
      }   
      catch (e) {
        console.log(e)
      }
    }, fetchDelay: 500,

    data(){
      return{
        docs: []
      }
    }
  }
</script>

Obviously you need to create some content on Prismic in order to retrieve something. So login and make the desired custom types and related content. Of course I won’t dive deep on how to query the api (their docs are also very good: https://prismic.io/docs/vuejs/query-the-api/how-to-query-the-api).

Wrapping up and deploy

If you didn’t already, join netlify. Pair your github account, select the repo to deploy, assign the nuxt generate to the master branch, connect your custom domain and start deploying! Every push you make to your repo will trigger a build (you can still disable that).

And that’s it! Now you only have to code a beautiful site/app.

Thank you…

#vuejs #nuxtjs #javascript

How to Build an E-commerce Website with Nuxt
13.40 GEEK