Nuxt 3, Tailwind, and Supabase Crash Course
Tags: vue, tailwindcss, javascript, webdev
Published: 2023-02-20 08:34:13

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 building a simple Cat Image Gallery with Nuxt 3, Tailwind, and [Supabase](https://supabase.com/) . Finally, we will deploy our app to Vercel so that it is accessible from anywhere around the world.

This written version of the course is also available as a video tutorial on my YouTube channel that you can check out below:

{% youtube A-G6lPHctPs %}

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

https://github.com/Baroshem/nuxt3-tailwind-supabase

## Technology Stack

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

We will be using cat images from the Placekitten API below:

![Placekitten](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o6zs007onhc2fs2kmq68.png)

For the connection to Supabase, we will be using an official Nuxt integration module:

![Nuxt Supabase](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d5y8rii2kfvnn9ny33fs.png)

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

![Nuxt Tailwind](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qqh7z6qd829yzoeixlux.png)

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

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

I have already added three records to Supabase table that I will fetch for this tutorial:

![Supabase Dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t0h1a2fvdek4qfw7rhwc.png)

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

## Code

I have generated a simple Nuxt 3 project using following command:

```bash
npx nuxi init <project-name>
```

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

```bash
yarn install
```

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

```bash
yarn dev
```

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 (Supabase, Tailwind, Image):

```bash
yarn add --dev @nuxt/image-edge @nuxtjs/tailwindcss @nuxtjs/supabase
```

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

```ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
    modules: ['@nuxtjs/supabase', '@nuxtjs/tailwindcss', '@nuxt/image-edge'],
})
```

In order to have optimized images, you should add following image configuration object as instructed [here](https://v1.image.nuxtjs.org/configuration#domains):

```ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
    modules: ['@nuxtjs/supabase', '@nuxtjs/tailwindcss', '@nuxt/image-edge'],
    image: {
        domains: ['placekitten.com']
    }
})
```

Also, don't forget about `.env` file for Supabase:

```bash
SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imh6a3JmbnJ0aGl2dGd5d3dmbXp3Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2NTAzNjQ5NjYsImV4cCI6MTk2NTk0MDk2Nn0.jnrnzs8luCdj2XyhaN2QDp8O6dGDgDOV9zUGN12X0fw
SUPABASE_URL=https://hzkrfnrthivtgywwfmzw.supabase.co
```

You can get this credentials here in Supabase settings:

![Supabase credentials](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9d7dr8i7khonu7uerbc.png)

Now, let's create `CatImage.vue` and `CatImageGallery.vue` components:

```vue
<template>
    <div class="flex flex-wrap w-1/3">
      <div class="w-full p-1 md:p-2">
        <NuxtImg
          class="block object-cover object-center w-full h-full rounded-lg"
          :alt="alt"
          format="webp"
          :src="src" />
      </div>
    </div>
  </template>
  
  <script setup lang="ts">
  const props = defineProps({
    src: {
      type: String,
      required: true,
    },
    alt: {
      type: String,
      required: true,
    }
  })
  </script>
```

As you can see, it is a really simple component that just displays an image by using `NuxtImg` component based on the passed props.

Next, let's create a `CatImageGallery` component that will be used to display a list of Cat Images based on props.

```vue
<template>
    <section class="overflow-hidden text-gray-700 ">
      <div class="container px-5 py-2 mx-auto lg:pt-12 lg:px-32">
        <div class="flex flex-wrap -m-1 md:-m-2">
          <cat-image
            v-for="image in images"
            :key="image.id"
            :alt="image.title"
            :src="image.src"
          />
        </div>
      </div>
    </section>
  </template>
  
  <script setup lang="ts">
  const props = defineProps({
    images: {
      type: Array,
      required: true,
    },
  })
  </script>
```

Nothing crazy here as well. Let's replace `app.vue` content with the following:

```vue
<template>
  <div>
    <CatImageGallery :images="images"/>
  </div>
</template>

<script setup lang="ts">
const client = useSupabaseClient()
const { data: images } = await useAsyncData('images', async () => client.from('images').select('*').order('created_at'), { transform: result => result.data })
</script>
```

Let's stop for a second here to discuss the content of `script` tag. We are using `useSupabaseClient` composable to initialize the Supabase client. 

Then, we are calling Nuxt `useAsyncData` where we are fetching results from Supabase in a SQL like way (`SELECT * FROM images ORDER BY created_at`). Finally, we are also transforming the response object format so that it is easier to work with.

After switching to the browser, you should see the following result:

![CatImage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jimtizg76ldt2t2hc30e.png)

## Deploying to Vercel

As our final step here, let's deploy our application to Vercel so that it is accessible from anywhere around the world.

![Vercel](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qi3elpqao14fhki6tnxq.png)

After selecting the project, we are asked to select configuration. In our case, the default one will work just fine:

![Deploying the project](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1wrssmmuzbzobf7rkkpe.png)

We only need to add the environment variables so that the deployed application will have access to them:

![Environment Variables](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mae3fc6wfgh4l04xy4ue.png)

If everything went smoothly, we should see the following result in the browser:

![App deployed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/85bmeje8tsh33an6e797.png)


## Summary

And that's it! You have just built a simple Cat Image Gallery with Nuxt 3, Tailwind, and Supabase! Let me know in the comments what topics you would like me to cover next :)