DEV Community

Cover image for Blazingly fast E-Commerce in Nuxt
Jakub Andrzejewski
Jakub Andrzejewski

Posted on

9

Blazingly fast E-Commerce in Nuxt

I recently participated as a speaker at Vue.js Amsterdam and during my talk, I announced a new project - Nuxt Commerce. It is an open source template for building performant e-commerce applications.

Nuxt Commerce

In this article, we’ll explore how does it work, what benefits does it bring, and how you can use it to build modern and efficient online shops based on Shopify.

Enjoy!

🤔 What is Nuxt Commerce?

A high-performance, server-rendered E-commerce app built with Nuxt & Shopify. You can check the repository here.

It comes with several useful features out of the box:

  1. Nuxt UI - A UI Library for Modern Web Apps.
  2. GraphQL Client - Minimal GraphQL Client + Code Generation
  3. Image Optimization - Resize and transform your images using built-in optimizer or your favorite images CDN
  4. Scripts - Load third-party scripts with better performance, privacy, security and DX
  5. Hybrid rendering - Set different caching rules and rendering modes per route using Route Rules
  6. SEO - Simple configuration for Sitemap.xml, Robots.txt, Meta, and OG Images
  7. JSON-LD - Lightweight Linked Data format for products

Nuxt Commerce is a Nuxt application after all. There is no additional layer of abstraction so if you are familiar with Nuxt framework already you will be able to start with Nuxt Commerce quickly.

🟢 How Nuxt Commerce helps build performant and SEO friendly websites?

Nuxt Commerce implements several Performance and SEO practices. Even if you don't use Nuxt Commerce project, you can still utilize them in your project to make your extisting application SEO friendly and performant!

Performance Improvements

The first issue you will encounted while building a modern Nuxt website is that you can load a code that is not needed for the user. We can solve that by utilizing the Lazy prefix while using the component in the page like following:

<template>
  <main>
    // other components
    <LazyTheFooter />
  </main>
</template>
Enter fullscreen mode Exit fullscreen mode

The second one will be about unoptimized scripts. We usually want to include third party scripts as fast as possible without really taking care about the performance implications. Adding scripts in the head of the document will result in render blocking and delaying the delivery of the content important for users. Nuxt Scripts module can help with that:

<script lang="ts" setup>
const { load } = useScriptGoogleAnalytics(
  {
    id: 'G-1234567',
    scriptOptions: { trigger: 'manual' }
  },
)

load()
</script>
Enter fullscreen mode Exit fullscreen mode

The third issue is related to the images. There are multiple ways we can optimize the to improve web performance such as modern formats, lazy loading, fetchPriority, width/height, and more. Nuxt Image module can help with that:

<NuxtImg
  src="/images/nuxt.png"
  alt="image"
  width="400"
  height="400"
  loading="lazy"
  fetch-priority="low"
/>
Enter fullscreen mode Exit fullscreen mode

Fourth one is related to blocking client side navigation due to data fetching. For the resources that are needed to be loaded later (i.e. product recommendations that are usually below the fold) we can instruct useAsyncData to be lazy like following:

const { data } = await useAsyncData(() => fetchRecommended(), { lazy: true })
Enter fullscreen mode Exit fullscreen mode

And finally, a fifth one is about lack of control over Hydration process. When I was developing the Nuxt Commerce, we needed to use external module like NuxtLazyHydrate but recently, Nuxt Core Team implemented this functionality in the core framework. But in general, the idea is to hydrate content with JavaScript after certain condition, i.e. when it is visible:

<template>
  <NuxtLazyHydrate when-visible>
    <RecommendedProducts />
  </NuxtLazyHydrate>
</template>
Enter fullscreen mode Exit fullscreen mode

SEO-friendly

When building performance websites, we cannot forget about SEO. Without it, users and Search Engines will not be able to find our website nor products - this is really bad for sales. We need to implement several SEO improvements to our website starting with the Sitemap.

In Nuxt, we can use Nuxt Sitemap - a great module that helps us build static and dynamic sitemaps for our website like:

export default defineSitemapEventHandler(async () => {
  const { products } = await GqlGetSitemapProducts({ first: 100 })

  const productUrls = products.edges.map(({ node }) => ({
    loc: `/product/${node.handle}`,
    lastmod: node.updatedAt,
  }))

  return productUrls
})
Enter fullscreen mode Exit fullscreen mode

With the approach above, we are always making sure that the sitemap is up to date with out products in e-commerce platform.

Next, we need to be able to set SEO meta dynamically for each of our pages. To do so, we will use built in SEO meta composable like so:

<script setup lang="ts">
useSeoMeta({
  title: 'My Amazing Site',
  ogTitle: 'My Amazing Site',
  description: 'This is my amazing site, let me tell you all about it.',
  ogDescription: 'This is my amazing site, let me tell you all about it.',
  ogImage: 'https://example.com/image.png',
  twitterCard: 'summary_large_image',
})
</script>
Enter fullscreen mode Exit fullscreen mode

In E-Commerce specific, we would also need to configure JSON LD for structured product data and we can do so like following:

useHead({
  script: [
    {
      type: 'application/ld+json',
      innerHTML: JSON.stringify({
        '@context': 'https://schema.org',
        '@type': 'Product',
        'name': product.value.title,
        'description': product.value.description,
        'image': product.value.featuredImage?.url,
        'offers': {
          '@type': 'AggregateOffer',
          'availability': product.value.availableForSale
            ? 'https://schema.org/InStock'
            : 'https://schema.org/OutOfStock',
          'priceCurrency': product.value.priceRange.minVariantPrice.currencyCode,
          'highPrice': product.value.priceRange.maxVariantPrice.amount,
          'lowPrice': product.value.priceRange.minVariantPrice.amount,
        },
      }),
    },
  ],
})
Enter fullscreen mode Exit fullscreen mode

To make our website more friendly for SEO, we would also need to configure robots.txt and we can do so again with the great Nuxt Robots module that delivers that with no configuration needed!

And finally, we want to be able to create dynamic OG images - another time here we have a great Nuxt module for that which we can use in the following way:

defineOgImageComponent('Nuxt', {
  title: 'Nuxt Commerce',
  description: 'A high-performance, server-rendered E-commerce app built with Nuxt & Shopify',
  theme: '#4ADE80',
  headline: '',
  colorMode: 'dark',
})
Enter fullscreen mode Exit fullscreen mode

This will result in a following image being generated when we send a link to our website to someone:

Nuxt Commerce

📖 Learn more

If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this link or by clicking the image below:

Vue School Link

It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉

✅ Summary

Damn, this was a lot of knowledge for one article but I wanted to share with you a great news about the release of Nuxt Commerce. I spent significant amount of time on it to deliver to you the performant and SEO friendly template for building modern e-commerce websites with Nuxt and Shopify. Remember to visit the repository and give me some feedback!

Take care and see you next time!

And happy coding as always 🖥️

Heroku

Built for developers, by developers.

Whether you're building a simple prototype or a business-critical product, Heroku's fully-managed platform gives you the simplest path to delivering apps quickly — using the tools and languages you already love!

Learn More

Top comments (2)

Collapse
 
joeschr profile image
JoeSchr • Edited

Is this in typescript or JavaScript? Does the graphql code generate "only" graphql or also the types for TS?
=> it's using typescript

Also what does pnpm run stackblitz do?
=> Seems Stackblitz is a Live editor and this is probably for demo purposes and such

Collapse
 
jacobandrewsky profile image
Jakub Andrzejewski

Hey there, the project is TypeScript fully. But you can also use normal JS in it if you like. The nuxt-graphql-client generates types for TS based on the grapqhl queries, mutations, and fragments and it also makes them auto imported to deliver great Developer Experience :)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

👋 Kindness is contagious

If you found this post useful, please drop a ❤️ or leave a kind comment!

Okay