Skip to content

Nuxt Integration Guide

This guide explains how to integrate Vue UI into a Nuxt application. It assumes you already have a fresh Nuxt project. If not, you can create one using the following command:

bash
npm create nuxt@latest

Before going further, you need to install the required dependencies.

pnpm
bash
pnpm add scule \
  defu \
  ohash \
  fuse.js \
  reka-ui \
  colortranslator \
  tailwind-variants \
  @vueuse/core \
  @vueuse/shared \
  @vueuse/integrations \
  @tanstack/table-core \
  @tanstack/vue-table \
  embla-carousel \
  embla-carousel-fade \
  embla-carousel-vue \
  embla-carousel-autoplay \
  embla-carousel-auto-scroll \
  embla-carousel-auto-height \
  embla-carousel-class-names \
  embla-carousel-wheel-gestures \
  vue-component-type-helpers

Configuring Nuxt

To ensure everything works seamlessly, you need to adjust the Nuxt configuration for dependency optimization, component resolution, and TypeScript paths.

Add the following configuration to your nuxt.config.ts file:

nuxt.config.ts
ts
import { fileURLToPath } from 'node:url'
import tailwindcss from '@tailwindcss/vite'

export default defineNuxtConfig({
  // ...

  future: {
    compatibilityVersion: 4
  },

  components: {
    dirs: [
      '~/ui/components',
    ],
  },

  imports: {
    dirs: [
      'ui/composables',
    ]
  },

  typescript: {
    tsConfig: {
      compilerOptions: {
        paths: {
          '@/ui': [
            '../app/ui',
          ],
        }
      }
    }
  },

  css: ['~/assets/css/main.css'],

  vite: {
    plugins: [
      tailwindcss(),
    ],
    optimizeDeps: {
      include: [
        'scule',
        'reka-ui',
        '@vueuse/core',
        '@vueuse/shared',
        'tailwind-variants',
        '@tanstack/vue-table',
      ]
    },
    resolve: {
      alias: {
        '@/ui': fileURLToPath(new URL('./app/ui', import.meta.url)),
      },
    },
  },
})

Here are some important aspects of the configuration to help you understand its purpose and functionality:

  1. Components Directory:
  • The components option specifies ~/ui/components as a directory for auto-registering components. This eliminates the need for manual imports, making component usage more straightforward.
  1. Imports Directory:
  • The imports option includes ui/composables, enabling automatic imports of composables from this directory. This simplifies the process of using composables throughout your project.
  1. TypeScript Path Mapping:
  • The typescript.tsConfig.compilerOptions.paths setting maps the alias @/ui to ../app/ui. This ensures that TypeScript correctly resolves the alias, providing accurate type checking and auto-completion in your development environment.
  1. CSS Integration:
  • The css array includes ~/assets/css/main.css, which serves as the main stylesheet for the project. This file integrates Tailwind CSS and custom styles, ensuring a consistent design system.
  1. Vite Configuration:
  • Plugins: The vite.plugins array includes the Tailwind CSS plugin, ensuring seamless integration with the Vite build tool.
  • Dependency Optimization: The optimizeDeps.include array pre-optimizes key dependencies (reka-ui, tailwind-variants, @vueuse/shared, @vueuse/core) to enhance the performance of the development server.
  • Alias Resolution: The resolve.alias block maps @/ui to the ./app/ui directory. This simplifies import paths and ensures consistency across the project.

These configurations are designed to streamline development and improve the overall developer experience when working with Vue UI in a Nuxt application.

Setting Up Tailwind CSS

For this section, you need to install Tailwind CSS and its dependencies:

pnpm
bash
pnpm add -D tailwindcss @tailwindcss/vite @egoist/tailwindcss-icons

To style your project, integrate Tailwind CSS using its Vite plugin:

  1. Add the plugin to your nuxt.config.ts file (already included in the configuration above).

  2. Import Tailwind CSS in your main style file, typically app/assets/css/main.css:

app/assets/css/main.css
css
@import "tailwindcss";
@plugin '@egoist/tailwindcss-icons';

@variant light (&:where(.light, .light *));
@variant dark (&:where(.dark, .dark *));

@theme default {
  --color-primary: var(--ui-primary);
  --color-secondary: var(--ui-secondary);
  // Add other custom variables here...
}

@layer base {
  body {
    @apply antialiased text-default bg-default scheme-light dark:scheme-dark;
  }

  :root {
    --ui-color-primary-500: var(--color-violet-500);
    --ui-color-secondary-500: var(--color-blue-500);
    // Define other colors and variables...
  }

  .dark {
    --ui-primary: var(--ui-color-primary-400);
    --ui-secondary: var(--ui-color-secondary-400);
    // Define dark theme variables...
  }
}

This setup allows you to define light and dark themes, customize colors, and use Tailwind's built-in CSS variables.

Example Usage

With everything set up, you can start using Vue UI components and composables.

vue
<script lang="ts" setup>
import App from '@/ui/components/App.vue'
</script>

<template>
  <App>
    <NuxtPage />
  </App>
</template>
vue
<script setup lang="ts">
const toast = useToast()
function onClick() {
  toast.add({
    title: 'Hey there!',
    description: 'This is a toast notification.',
  })
}
</script>

<template>
  <div class="p-4 flex flex-col items-start gap-2">
    <h1 class="text-2xl font-bold">
      Welcome to Vue UI
    </h1>

    <Button label="Click Me" @click="onClick" />
  </div>
</template>

NOTE

To prevent circular dependencies, the App.vue component must be explicitly imported in the app.vue file. This avoids issues where app/app.vue might attempt to auto-import itself.

You're now ready to build your project with Vue UI!