---
title: "Install maz-ui with Nuxt"
description: "The ultimate Nuxt module for Maz-UI - zero-config setup with auto-imports, theming, internationalization and powerful features out of the box"
package: "@maz-ui/nuxt"
url: "https://maz-ui.com/ecosystem/nuxt"
---

# Install maz-ui with Nuxt

> The ultimate Nuxt module for Maz-UI - zero-config setup with auto-imports, theming, internationalization and powerful features out of the box

- Package: `@maz-ui/nuxt`
- Web: https://maz-ui.com/ecosystem/nuxt

**Maz-UI Nuxt Module** provides zero-configuration setup, intelligent auto-imports, powerful theming capabilities and internationalization.

**Tip: Model Context Protocol (MCP)**

In development, the module can connect the AI coding agents detected in the project (Claude Code, Cursor, Copilot...) to the maz-ui [MCP server](https://maz-ui.com/ecosystem/mcp.md), which gives them the docs and rules of the installed maz-ui (opt-in with `agents: { mcp: true }`). See AI Agents.

Check out the documentation of [@maz-ui/mcp](https://maz-ui.com/ecosystem/mcp.md)

## Why Choose Maz-UI for Nuxt?

- **Zero Configuration** - Works out of the box with sensible defaults
- **Advanced Theming** - Built-in dark mode, custom themes, and CSS variables
- **Auto-Import Everything** - Components, composables, and directives automatically available
- **Performance Optimized** - Tree-shaking, lazy loading, and SSR-friendly CSS injection
- **Developer Experience** - TypeScript support, DevTools integration, and IntelliSense
- **Production Ready** - SSR/SSG support with client-side hydration

## Installation

```bash [pnpm]
pnpm add @maz-ui/nuxt
```

```bash [npm]
npm install @maz-ui/nuxt
```

```bash [yarn]
yarn add @maz-ui/nuxt
```

```bash [nuxt]
pnpx nuxt@latest module add @maz-ui/nuxt
```

Add the module to your `nuxt.config.ts`:

```ts
export default defineNuxtConfig({
  modules: ['@maz-ui/nuxt']
})
```

That's it! 🎉 All components and composables are now auto-imported and ready to use.

## Quick Start

### Instant Usage

No imports needed - everything is auto-imported:

```vue
<script setup>
// Composables are auto-imported
const { start, stop, pause, resume, remainingTime } = useTimer({
  timeout: 4000,
  callback: () => console.log('Timeout end')
})
const { toggleDarkMode, isDark } = useTheme()
</script>

<template>
  <div class="bg-surface p-8 text-foreground">
    <!-- Components are auto-imported -->
    <MazBtn color="primary" @click="start">
      Start timer ({{ remainingTime }}ms)
    </MazBtn>

    <!-- Directives work globally -->
    <MazBtn @click="toggleDarkMode">
      Toggle dark mode ({{ isDark ? '🌙' : '☀️' }})
    </MazBtn>
  </div>
</template>
```

## Configuration

### Minimal Setup

For most use cases, no configuration is needed:

```ts
export default defineNuxtConfig({
  modules: ['@maz-ui/nuxt']
  // That's it! 🎉
})
```

### Advanced Configuration

Customize everything to your needs:

```ts
export default defineNuxtConfig({
  modules: ['@maz-ui/nuxt'],
  mazUi: {
    // General Settings
    general: {
      autoImportPrefix: 'Maz', // useMazToast instead of useToast
      defaultMazIconPath: '/icons', // Default path for <MazIcon />
      devtools: true, // Enable DevTools integration
      preventIosInputZoom: true, // No zoom on focused fields on iOS
    },

    // CSS & Styling
    css: {
      injectCss: true, // Auto-inject Maz-UI styles
    },

    // Theming System
    theme: {
      preset: 'maz-ui', // 'maz-ui' | 'pristine' | 'ocean' | 'obsidian' | 'nova' | 'folio' | custom object
      strategy: 'runtime', // 'runtime' | 'buildtime'
      darkModeStrategy: 'class', // 'class' | 'media'
      darkClass: 'dark', // class on <html> when colorMode === 'dark' (default: 'dark')
      lightClass: 'light', // class on <html> when colorMode === 'light' (default: 'light')
      overrides: {
        colors: {
          light: { primary: 'oklch(0.65 0.19 254)' },
          dark: { primary: 'oklch(0.72 0.18 254)' }
        }
      },
      mode: 'both', // 'light' | 'dark' | 'both'
    },

    // Translations
    translations: {
      locale: 'fr',
      fallbackLocale: 'en',
      messages: {
        // override default messages or add new languages:
        // the path of a file that exports the messages (loaded when the locale is used)
        fr: '~/locales/maz-ui/fr.ts',
        // or the messages
        nl: { pagination: { navAriaLabel: 'Paginanavigatie' } },
      },
    },

    // Components
    components: {
      autoImport: true, // All components globally available
    },

    // Global component defaults (priority: instance prop > defaults[Component] > defaults.global > library default)
    defaults: {
      global: { roundedSize: 'lg' }, // cross-cutting (roundedSize, size)
      MazBtn: { roundedSize: 'full' }, // per-component, wins over global
      MazCard: { bordered: false, elevation: true },
    },

    // Country flags of MazSelectCountry and MazInputPhoneNumber: 'cdn' (default), 'local' (offline) or '/flags/{code}.svg'
    flags: 'local',

    // Plugins (not enabled by default)
    plugins: {
      aos: true,
      dialog: true,
      toast: true,
      wait: true,
    },

    // Composables (enabled by default)
    composables: {
      useFormValidator: true,
      useFreezeValue: true,
      useIdleTimeout: false,
      useInstanceUniqId: false,
      useMountComponent: false,
      useReadingTime: false,
      useStringMatching: false,
    },

    // Directives (not enabled by default)
    directives: {
      vTooltip: true,
      vLazyImg: true,
      vClickOutside: true,
      vFullscreenImg: true,
      vZoomImg: true,
    },

    // AI coding agents (default: { rules: false, mcp: false }, true to enable everything)
    agents: { rules: true, mcp: true },
  }
})
```

## Complete Configuration Reference

### General Configuration

```ts
const general = {
  // Add prefix to all auto-imported composables
  autoImportPrefix: 'Maz', // only for composables, generates useMazToast, useMazTheme, etc.

  // Default icon path for <MazIcon icon="..." />
  defaultMazIconPath: '/icons',

  // Enable Nuxt DevTools integration
  devtools: true,

  // Stop iOS from zooming the page when a form field gets the focus (default: false)
  // Adds `maximum-scale=1` to the viewport on iOS only, see the preventIosInputZoom helper of @maz-ui/utils
  preventIosInputZoom: false,
}
```

### CSS Configuration

```ts
const css = {
  // Auto-inject Maz-UI base styles
  injectCss: true,
}
```

### Theme System

The most powerful theming system for Nuxt applications:

```ts
const theme = {
  // Use predefined presets or create custom ones
  preset: 'maz-ui', // 'mazUi' | 'dark' | 'ocean' | CustomThemeObject

  // Override specific parts of the theme
  overrides: {
    colors: {
      light: {
        primary: 'oklch(0.6 0.18 254)',
        secondary: 'oklch(0.96 0.01 254)',
        surface: 'oklch(1 0 0)',
        foreground: 'oklch(0.16 0.02 254)',
      },
      dark: {
        primary: 'oklch(0.72 0.18 254)',
        secondary: 'oklch(0.22 0.02 254)',
        surface: 'oklch(0.16 0.02 254)',
        foreground: 'oklch(0.96 0.005 254)',
      }
    },
    // Override other theme properties...
  },

  // Supported color modes to use
  mode: 'both', // 'light' | 'dark' | 'both'

  // Initial color mode to use (only if mode is 'both')
  colorMode: 'auto', // 'light' | 'dark' | 'auto'

  // CSS generation strategy
  strategy: 'runtime', // 'runtime' (recommended) | 'buildtime'

  // Dark mode handling
  darkModeStrategy: 'class', // 'class' | 'media'

  // Class added to <html> when colorMode === 'dark' (default: 'dark')
  darkClass: 'dark',

  // Class added to <html> when colorMode === 'light' (default: 'light')
  // Mirror of darkClass - used to force `color-scheme: only light`.
  lightClass: 'light',

  // Persist the active preset name in the `maz-preset` cookie so the
  // user's last-used theme is restored on reload. Default: true.
  persistPreset: true,
}
```

The server renders the theme of the user: the preset and the color mode come from the `maz-color-mode` and `maz-preset` cookies, and the system preference from the `Sec-CH-Prefers-Color-Scheme` client hint (or the cookie of the previous visit). A blocking script applies the live system preference before the first paint. See the [persistence of the user preferences](https://maz-ui.com/ecosystem/themes.md#persistence-of-the-user-preferences).

### Global Component Defaults

Set default prop values once for every component. Resolution priority, per prop: instance prop > `defaults[Component]` > `defaults.global` > library default. A global default never overrides a prop set on the instance.

```ts
const defaults = {
  // Cross-cutting tokens applied to every component that exposes them
  global: {
    roundedSize: 'lg', // 'none' | 'sm' | 'md' | 'lg' | 'xl' | 'full'
    size: 'sm', // 'mini' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'
  },
  // Per-component defaults, strongly typed as Partial<ComponentNameProps>, win over `global`
  MazBtn: { roundedSize: 'full' },
  MazCard: { bordered: false, elevation: true },
  MazContainer: { bordered: false },
}
```

See the [Global component defaults guide](https://maz-ui.com/guide/global-defaults.md) for the full list of globalizable props.

### Country Flags

Source of the flags of `MazSelectCountry` and `MazInputPhoneNumber`. A `flag-src` set on a component wins.

```ts
export default defineNuxtConfig({
  mazUi: {
    // 'cdn' (default): flagcdn.com
    // 'local': flags of @maz-ui/icons, one chunk per flag loaded when visible, no request to a third party
    // '/flags/{code}.svg': your own files ({CODE} for uppercase codes)
    flags: 'local',
  },
})
```

Nothing is added to your build unless `flags` is `'local'`. See [MazSelectCountry](https://maz-ui.com/components/maz-select-country.md#flags-source) for the details (Content Security Policy, PWA precache).

## Theme Strategies Explained

### Runtime (Recommended)

The full theme CSS is generated and injected synchronously on first paint:

- **No FOUC** - The full stylesheet is rendered in the document head before the first paint
- **SSR-friendly** - On Nuxt SSR, the CSS is inlined via `useHead` during server rendering and re-used on the client
- **Dynamic** - `useTheme().updateTheme(...)` re-injects the new CSS on the fly

```ts
export default defineNuxtConfig({
  mazUi: {
    theme: {
      strategy: 'runtime' // Recommended for most use cases
    }
  }
})
```

### Buildtime

Build-time CSS generation strategy:

- **No runtime injection** - CSS is generated at build time and must be included manually
- **Consumer responsibility** - You must handle CSS inclusion in your build process and HTML
- **Optimal performance** - No client-side CSS generation overhead
- **Static themes only** - Best for applications without dynamic theme switching

```ts
export default defineNuxtConfig({
  mazUi: {
    theme: {
      strategy: 'buildtime' // For static sites with predefined themes
    }
  }
})
```

### Components

```ts
const components = {
  // Auto-import all 50+ Maz-UI components
  autoImport: true,
}
```

**Available Components:**
`MazBtn`, `MazInput`, `MazSelect`, `MazDialog`, `MazToast`, `MazIcon`, `MazCard`, `MazTable`, `MazChart`, `MazCarousel`, `MazGallery`, and 50+ more!

### 🎪 Composables

All composables are auto-imported and ready to use:

```ts
const composables = {
  // 🎨 Theming
  useTheme: true, // Theme management and dark mode

  // 🌐 Translations
  useTranslations: true, // Translation management

  // 📱 Responsive & Detection
  useWindowSize: true, // Reactive window dimensions
  useBreakpoints: true, // Responsive breakpoints
  useUserVisibility: true, // Page visibility detection
  useIdleTimeout: true, // User idle detection

  // 🛠️ Utilities
  useTimer: true, // Timer and countdown
  useFormValidator: true, // Form validation
  useStringMatching: true, // String utilities
  useReadingTime: true, // Reading time calculation
  useDisplayNames: true, // Display localized names
  useSwipe: true, // Swipe gestures
  usePullToRefresh: true, // Pull to refresh gesture

  // 🔧 Advanced
  useFreezeValue: true, // Freeze reactive values
  useInjectStrict: true, // Strict dependency injection
  useInstanceUniqId: true, // Unique IDs generation
  useMountComponent: true, // Dynamic component mounting
}
```

### Plugins

```ts
const plugins = {
  // Animations
  aos: true,
  // 🎭 Display modales without any implementation in template
  dialog: true,
  // 🎭 UI Notifications
  toast: true,
  // 🔄 Loading States
  wait: true,
}
```

### Directives

Powerful Vue directives for enhanced functionality:

```ts
const directives = {
  // Image directives
  vLazyImg: { threshold: 0.1 }, // Lazy loading with intersection observer
  vZoomImg: true, // Click to zoom images
  vFullscreenImg: true, // Fullscreen image viewer

  // Interaction directives
  vTooltip: { position: 'top' }, // Flexible tooltips
  vClickOutside: true, // Detect outside clicks
}
```

### AI Agents

Connect your AI coding agents (Claude Code, Cursor, GitHub Copilot, Codex, Windsurf...) to maz-ui, version-matched with the installed maz-ui, so they use its components, composables, icons, helpers and theme tokens instead of re-implementing them:

```ts
const agents = {
  // Register the maz-ui MCP server in .mcp.json, .cursor/mcp.json, .vscode/mcp.json (default: false)
  // Its instructions give the maz-ui rules to the agents
  mcp: true,
  // Also write the rules in .claude/rules/maz-ui.md and in AGENTS.md, for agents without MCP (default: false)
  rules: false,
  // 'claude' | 'agents-md' | 'cursor' | 'vscode' (default: the detected agents)
  targets: ['claude', 'agents-md'],
  // Folder where the files are written, relative to the Nuxt app (default: the root of the workspace)
  dir: '../..',
}
// agents: true enables mcp and rules, agents: false disables everything
```

In a monorepo, the files are written at the **root of the workspace** (`workspaceDir` of Nuxt), where your agents start, not in the Nuxt app: a single `.mcp.json` serves every app. Set `dir` to choose another folder.

The module runs in development only (never in CI nor in tests), only for the agents it detects in the project (`.claude/`, `CLAUDE.md`, `.mcp.json`, `.cursor/`, `.vscode/mcp.json`, `.github/copilot-instructions.md`, `AGENTS.md`, `.codex/`, `.windsurf/`...), and keeps the files up to date when you upgrade maz-ui:

- `.mcp.json`, `.cursor/mcp.json`, `.vscode/mcp.json`: a `maz-ui` server entry, added only when no maz-ui MCP server is already registered
- with `rules: true`, `.claude/rules/maz-ui.md`: a Claude Code rule (skipped when Claude reads `AGENTS.md`, i.e. without `CLAUDE.md`)
- with `rules: true`, `AGENTS.md`: a section delimited by `<!-- BEGIN:maz-ui -->` and `<!-- END:maz-ui -->`, read by Codex, Cursor, Copilot, Windsurf...

It never overwrites a file it does not own: your `CLAUDE.md`, your own rules and the other MCP servers are left untouched, and an existing `maz-ui` server entry (for example pinned to a version) is kept as is. Commit the generated files to share them with your team (check that `.claude/` is not in your `.gitignore`). See the [AI agents guide](https://maz-ui.com/guide/ai-agents.md) for details.

## Advanced Theming

### Custom Theme Creation

```ts
import { definePreset } from '@maz-ui/themes'

export const customTheme = definePreset({
  base: 'maz-ui',
  overrides: {
    name: 'custom',
    foundation: {
      'base-font-size': '14px',
      'font-family': `Manrope, sans-serif, system-ui, -apple-system`,
      'space': '0.25rem',
      'border-width': '0.0625rem',
    },
    scales: {
      rounded: { md: '0.7rem' },
    },
    colors: {
      light: {
        primary: 'oklch(0.65 0.27 5)', // Custom pink
        secondary: 'oklch(0.96 0.01 5)',
        surface: 'oklch(1 0 0)',
        foreground: 'oklch(0.16 0.02 254)',
        muted: 'oklch(0.6 0.01 254)',
        accent: 'oklch(0.7 0.05 5)',
        destructive: 'oklch(0.6 0.22 27)',
        divider: 'oklch(0.92 0.005 254)',
      },
      dark: {
        primary: 'oklch(0.75 0.22 5)',
        secondary: 'oklch(0.24 0.02 5)',
        surface: 'oklch(0.16 0.02 254)',
        foreground: 'oklch(0.96 0.005 254)',
        muted: 'oklch(0.6 0.01 254)',
        accent: 'oklch(0.3 0.04 5)',
        destructive: 'oklch(0.55 0.2 27)',
        divider: 'oklch(0.3 0.01 254)',
      }
    },
  },
})

export default defineNuxtConfig({
  modules: ['@maz-ui/nuxt'],
  mazUi: {
    theme: {
      preset: customTheme,
      strategy: 'runtime',
    }
  }
})
```

**Tip: Subtree Overrides with MazUiProvider**

You can use [`MazUiProvider`](https://maz-ui.com/guide/maz-ui-provider.md) within a Nuxt app to override theme or translations in a specific subtree, while the module handles global defaults.

## Troubleshooting

### Two versions of maz-ui

If the module warns `The app installs maz-ui X and @maz-ui/nuxt uses maz-ui Y`, your app and the module load two copies of `maz-ui`: the options of the module (`mazUi.general`, `mazUi.plugins`...) may not apply to the components. Install the same version of `maz-ui` and `@maz-ui/nuxt`, they are released together:

```bash
npm install maz-ui@latest @maz-ui/nuxt@latest
```

See [Keep the packages on the same version](https://maz-ui.com/guide/getting-started.md#keep-the-packages-on-the-same-version).

### Theme System Issues

If you encounter the error `"useTheme must be used within MazUi plugin or MazUiTheme plugin installation"`, ensure that:

1. **Enable useTheme composable** in your configuration:

```ts
export default defineNuxtConfig({
  mazUi: {
    composables: {
      useTheme: true,
    }
  }
})
```

2. **Theme system is not disabled**:

```ts
export default defineNuxtConfig({
  mazUi: {
    theme: {
      // theme config, not false
      preset: 'maz-ui'
    }
  }
})
```
