DEV Community

Cover image for Nuxt, Medusa, TailwindCSS Crash Course
Jakub Andrzejewski
Jakub Andrzejewski

Posted on • Updated on

Nuxt, Medusa, TailwindCSS Crash Course

I really enjoyed building apps with Nuxt. It is currently my favourite web framework with tons of modules, plugins, and configuration options.

In this article, I will be showing you how you can build a simple Product Gallery (and in the future, powerful Headless Commerce website) with Nuxt, Tailwind, and Medusa.

This article will also showcase a Nuxt Module that I have recently created -> Make sure to star it on🚀 GitHub as it motivates me to make the module even better!

In the upcoming weeks I will also record a video tutorial on my YouTube channel about the same topic.

All the code from this tutorial is available in following GitHub repository:

Technology Stack

Before we jump into an actual code, let's talk briefly about our technology stack.

For the connection to Medusa, we will be using an module that I have recently created called nuxt-medusa :

Nuxt Medusa

For styling, I will be also using an official Nuxt Tailwind module:

Nuxt Tailwind

And for image optimization, the official Nuxt module as well:

Nuxt Image

Let's now go to the code to see how we can build our application with previously mentioned technologies:


I have generated a simple Nuxt project using following command:

npx nuxi init <project-name>
Enter fullscreen mode Exit fullscreen mode

Then, I have opened the project in my IDE and installed all the dependencies by using this command:

yarn install
Enter fullscreen mode Exit fullscreen mode

To see if it works correctly, let's just run the application with following command:

yarn dev
Enter fullscreen mode Exit fullscreen mode

If installation and build was successful, we should see a nice looking Nuxt Hello World page once we visit http://localhost:3000.

Now, let's install all required modules (Medusa, Tailwind, Image):

yarn add --dev @nuxt/image-edge @nuxtjs/tailwindcss nuxt-medusa
Enter fullscreen mode Exit fullscreen mode

And next, let's add them to modules section in nuxt.config.ts file:

export default defineNuxtConfig({
    modules: ['nuxt-medusa', '@nuxtjs/tailwindcss', '@nuxt/image-edge'],
Enter fullscreen mode Exit fullscreen mode

In order to have optimized images, you should add following image configuration object as instructed here:

export default defineNuxtConfig({
    image: {
        domains: ['']
Enter fullscreen mode Exit fullscreen mode

If you do not have a Medusajs project yet, you can generate one by running following command:

npx create-medusa-app
Enter fullscreen mode Exit fullscreen mode

Medusa will have a CORS setting for a storefront by default set to http://localhost:8000 in the medusa-config.js file so let's change it to http://localhost:3000 (default nuxt app port).

// CORS to avoid issues when consuming Medusa from a client
const STORE_CORS = process.env.STORE_CORS || "http://localhost:3000";
Enter fullscreen mode Exit fullscreen mode

Also, don't forget about .env file for Medusa (which is by default running on port 9000):

Enter fullscreen mode Exit fullscreen mode

Now, let's add the following code to the app.vue global component (I will explain each section below):

<script lang="ts" setup>
const client = useMedusaClient();
const { products } = await client.products.list();

  <div class="flex">
    <div v-for="product in products" class="mx-2">
      <div class="relative rounded-lg shadow-lg">
          class="shadow-lg rounded-lg opacity-1 hover:opacity-75 transition duration-300 ease-in-out w-full"
        <div class="p-6">
          <h5 class="font-bold text-lg mb-3">{{ product.title }}</h5>
          <pre class="text-gray-500 mb-4">{{
          <p>{{ product.description }}</p>
Enter fullscreen mode Exit fullscreen mode
  1. In the script section we are calling a useMedusaClient composable to have access to the Medusa client.
  2. We are using this client to fetch the product list and destructure products from it.
  3. In the template section we are using these products to generate multiple product cards by utilizing a v-if. We are also applying some Tailwind classes to make the elements look much nicer. We are also using the NuxtImg component with attribute format set to webp. This ensures that our images will have lighter webp format and will be fetched faster.

If we did everything correctly, we should see the following result once we visit http://localhost:3000:

Nuxt, Medusa, Tailwind


And that's it! You have just built a simple Product Gallery with Nuxt, Tailwind, and Medusa! Don' forget to star the project on GitHub :)

Oldest comments (1)

nicklasgellner profile image
Nicklas Gellner