Nuxt is an Intuitive Web Framework that allows you to build your next Vue.js application with confidence. An open source framework under MIT license that makes web development simple and powerful.
It comes with several useful features like:
Optimized with code-splitting, tree-shaking, optimized cold-start, link prefetching, payload extraction, just to name a few. Fast by default so you can focus on building.
Decide what rendering strategy at the route level: SSR, SSG, CSR, ISR, ESR, SWR. Build any kind of website or web application with optimized performance in mind.
By leveraging server-side rendering, ESM format and optimized images, Nuxt websites are indexable by search engines while giving the feeling of an app to the end-users.
Read more about it in the official documentation → https://nuxt.com/
We will be using this framework for our storefront (the frontend of e-commerce application) that will connect later on to the Shopify platform by using the Apollo GraphQL and to Storyblok as CMS.
Getting started with Nuxt
In order to get started with Nuxt, the best place to go is the official documentation → https://nuxt.com/docs/getting-started/installation. We will create a simple Nuxt application with the following command in the terminal:
This will create a simple Nuxt starter application. We can start this project to see if it works as expected (also, remember to install the dependencies with the package manager of your choice (in my case it was yarn).
Running the project requires the below command:
The project should be running right now and when we access the browser we should see the following result:
Now, if that went well, we can move to the next section about adding a bit of styling so that our future e-commerce application will look a bit better.
Adding styling with TailwindCSS
One of the things that I love about Nuxt is its ecosystem of modules. They extend the default functionality of the core framework and deliver a great Developer Experience.
Let’s add @nuxtjs/tailwindcss module to our application so that we can have easy and flexible styling for our e-commerce website.
Install the module with the following command:
And now, let’s add it to the modules array in nuxt.config.ts file:
And that’s it! We now have TailwindCSS installed in our application and we can test it out by replacing the code in app.vue component to something like this:
The basic layout of our e-commerce website
To have better reusability of our storefront application elements, let’s create a layout that will be shared across our pages. We will create two components, namely TheHeader and TheFooter and finally a layout that we will be using for our upcoming pages.
Let’s start with TheHeader component that will be a simple navigation with just a logo of Nuxt (company logo) on the left side of the page. I have already added a logo.svg in the /public/logo.svg so that we could use it easily in our app.
As you can see here, it is a simple nav element with NuxtLink that when clicked will redirect the user to the homepage. Nothing crazy here 😀
Next, we will create TheFooter component that will be responsible for displaying a footer tag with two links; first to the Nuxt website, and second to your Twitter:
Nothing crazy here as well. Now, let’s create a default.vue layout and add two previously created components there:
The content of our pages (home page and product page) will be rendered in <slot />. Finally, let’s add this layout in our global app.vue component:
The <NuxtPage /> will not work yet as we have not created any pages yet (also, the warning in the console will confirm that → Create a Vue component in the pages/ directory to enable <NuxtPage>) but no worries, we will do that in the next section.
If we did everything correctly, we should see the following result in the browser:
We have a header component with the Nuxt logo and also a footer with a link to Nuxt and made by me link. In the next section, we will create the homepage of our e-commerce website.
Homepage with Banner and Product List
In this section, we will be creating two new components, namely HeroBanner.vue and ProductCard.vue as well as the new page. We won’t be fetching any data yet but instead we will mock the data for now. We will also add a new module @nuxt/image that will be responsible for optimizing our images so that they are more performant out of the box.
To use the @nuxt/image module in our Nuxt app we will use the official docs
In order to use it, we will first install it:
And then, add it to our modules array in nuxt.config.ts file:
And that’s it! We can now use NuxtImg component in our app.
You may be wondering why we are using the image-edge version. At the time of me writing this article, this is the recommended version of the image module to work with Nuxt 3
For our new components, let’s start with Hero Banner. As its name suggests it will be the first banner that our users will see so we want to make it big and with a catchy phrase at the top.
The second part of this component is simple, we are just displaying a div with a green text, but let’s stop for a second to discuss what is happening in NuxtImg component.
We are using the component from image module and we are passing a prop attribute format. In here we are saying what format we would like this image to be. So, instead of heavy .jpg we would prefer to have a lighter alternative of .webp that is supported by all modern browsers. The optimization won’t work yet as we need to apply some configuration to the image module.
By default, the IPX image optimizer that the image module is using, needs to have a list of domains that can be used for optimizing the images. For now, what would happen is that our Banner would be displayed, but it wont be optimized. In order to enable the optimization, we need to add the mdbootstrap.com to the allowed domains for IPX. Let’s do this below:
Let’s now create our homepage so that we could display the HeroBanner.vue component there:
Thanks to the Nuxt auto-import feature, we do not need to write any import statements.
If we did everything correctly, we should see the following result in the browser:
Now, let’s create a ProductCard.vue component that will be responsible for displaying the data about our product (mocked for now).
This component will accept a few props that will be used to display content about our product in a nice way.
Let’s add it to our index.vue (Home Page) to see how it looks like. I will create an array of mocked products to display a list of three products below the HeroBanner.vue component.
Nothing crazy here as well, we are just creating three components out of the array of mocked products. Later on, we will replace this array with actual data from the Shopify platform.
Product Detail Page
Apart from the Home Page, our e-commerce application would need a solid Product Page that would showcase our product, and related products and would allow us to buy the actual product.
Let’s create a new page in /pages/products/[handle].vue.
The path in our project will resemble the URL in the browser so:
If we did everything correctly, we should see the following result in the browser:
Apart from that, let’s also add the same list of products from the HomePage (don’t bother about code duplication right now, everything will be fixed once we will fetch the real data from Shopify 😀)
Apart from the product detail, we also have a carousel below that shows a list of products (in the future those products will be related to the main product).
That was a lot of work so let’s take a short brake and let’s move to the next section where we will be replacing the mocked data, with real data from Shopify.
Senior Developer @VueStorefront, Ambassador @Nuxt.js and @Storyblok. Apart from work, Technical and Recreational Diver, Mountain Hiker, occasional gamer, and a huge fan of Lego and Transformers.