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!