A new Splitter component lets you build layouts with resizable panels separated by draggable handles, with min/max sizes, collapsible panels, nesting and vertical orientation:
A new ProgressGroup component displays multiple values as segments of a single progress bar, with a legend listing each item. Items take any theme color or a CSS color, and the status prop shows the total:
Animations and movement transitions now all run on --ease-out, exits included. Override the token in your @theme to retime the whole library, see the Motion section:
The @nuxt/ui/vite plugin now supports experimental.componentDetection like the Nuxt module. It scans your source and only generates the theme CSS for the components you use:
Nuxt UI now embeds the icons it uses into your build, so they render straight away during SSR and work fully offline instead of being fetched from the Iconify API at runtime. As long as the collection is installed locally, this happens automatically for Nuxt UI's own icons (the lucide collection by default), on both Nuxt and pure Vue/Vite.
On Nuxt this rides on @nuxt/icon's existing client bundle. On Vue the @nuxt/ui/vite plugin gains an icon.clientBundle option to bring the same bundling to Vite, either by listing icons or by scanning your source. This is powered by the standalone Vite plugin and utils added in @nuxt/icon v2.3.0:
vite.config.ts
import ui from '@nuxt/ui/vite'
export default defineConfig({
plugins: [
ui({
icon: {
clientBundle: {
// list them explicitly...
icons: ['lucide:heart', 'simple-icons:github'],
// ...or scan your whole app
scan: true
}
}
})
]
})
!TIP
Install each collection you use with @iconify-json/{collection_name} so its icons can be bundled. See the Icons integration for the details.
The Modal and Slideover components now accept the unmountOnHide prop. Set it to false to keep their content mounted while closed so form state, scroll position and expensive children survive open/close cycles:
<template>
<UModal :unmount-on-hide="false">
<UButton label="Open" />
<template #content>
<!-- kept alive when the modal is closed -->
</template>
</UModal>
</template>
The Calendar component gains a single type prop (date | month | year, default date) that renders it as a day, month or year picker, covering both standalone pickers and quick navigation:
!TIP
In date mode the heading also becomes a clickable button that cycles day → month → year, so you can jump to a month or year without clicking through prev / next repeatedly. This is controlled by the new viewControls and viewButton props and works with range.
The new useTour composable drives guided tours by re-anchoring a single Popover across steps. It owns the step state and resolves each step's target into a reference you bind to <UPopover>, while you keep full control over the content and navigation:
A new build-time theme.unstyled option strips Nuxt UI's default theme classes from every component, keeping only their structure and the classes you provide through class, ui or app.config.ui. This lets you bring your own design system on top of the components' logic and accessibility, or cut HTML and bundle bloat:
!WARNING
This strips structural classes too (positioning, transitions, flex/grid), not just cosmetic ones. Layout-heavy components like Modal, Drawer or Calendar will need you to re-supply their layout.
For more surgical control, slot classes can now be a (defaults) => classesfunction that replaces the slot's defaults instead of merging onto them. It receives the resolved defaults so you can reuse part of them, while plain strings keep merging exactly as before. It works in :ui, app.config.ui and <UTheme :ui>:
Every component now shares a single focus-visible language: a soft outline halo tinted with the component's color (e.g. outline-primary/25), so the indicator stays consistent and accessible across every variant and color. Tab panels, scrollable regions and overlay links that browsers make focusable now show the halo too, instead of hiding focus entirely.
If you prefer one outline color across your whole app regardless of component color, a single global rule in your main.css does it:
The Theme component can now override default prop values for all descendant components. Pass a props object where keys are component names and values are their prop overrides:
Explicit props on a component always take priority. Theme components can be nested (innermost wins) and propagate through the entire tree via provide / inject.
InputMenu: rename autocomplete prop to mode to free up HTML attribute (#6474)
The boolean autocomplete prop introduced in v4.6.0 collided with the standard HTML autocomplete attribute used for browser autofill (address-line1, one-time-code, email, etc.). It has been renamed to mode which accepts 'combobox' | 'autocomplete' (defaults to combobox). The HTML autocomplete attribute now falls through to the inner input like other form components.
The Listbox component is a selectable list of items with built-in search, virtualization, and rich item rendering. It's ideal when you want an always-visible list without the overlay behavior of SelectMenu.
The ProsePrompt component displays pre-built AI prompts inside your docs with one-click copy and direct IDE integration. Users can copy the prompt to their clipboard or open it directly in Cursor or Windsurf via the actions prop.
::prompt
---
description: Build a dashboard layout with Nuxt UI.
icon: i-lucide-layout-dashboard
actions:
- copy
- cursor
- windsurf
---
You are a Nuxt UI expert. Help me build a dashboard layout with
a collapsible sidebar and a sticky top navbar.
::
The Link component now integrates automatically with @nuxtjs/i18n when installed. Internal links are localized using the $localePath helper under the hood (#5537).
<template>
<!-- Automatically becomes /en/about or /fr/about based on current locale -->
<ULink to="/about">About</ULink>
</template>
This also propagates to every component that accepts a to prop (NavigationMenu, Breadcrumb, DropdownMenu, CommandPalette, etc.), so routes stay locale-aware across your entire app.
The Sidebar component provides a responsive application sidebar that stays fixed on desktop and transforms into a Modal, Slideover, or Drawer on mobile. It supports three visual variants (sidebar, floating, inset) and three collapsible modes (offcanvas, icon, none):
module: use moduleDependencies to manipulate options (#5384)
This release adopts Nuxt's new moduleDependencies API to declaratively manage sub-module dependencies (@nuxt/icon, @nuxt/fonts, @nuxtjs/color-mode, @nuxtjs/mdc) instead of manually installing them at runtime. This requires Nuxt >= 4.1.0.
The Theme component lets you override the theme of all child components without modifying each one individually. Pass an object to the ui prop where keys are component names and values are their slot class overrides:
The Theme component doesn't render any HTML element. It uses Vue's provide / inject under the hood, so overrides propagate through the entire component tree regardless of nesting depth. Theme components can be nested (innermost wins) and the ui prop on individual components always takes priority.
Thanks to Tailwind CSS v4.2, four new neutral color options are now available: taupe, mauve, mist and olive. Configure them through the ui.neutral option in your app.config.ts.
We're introducing a suite of 6 new components to build rich text editors, powered by TipTap:
Editor: The root component supporting JSON, HTML, and Markdown content types.
EditorToolbar: A customizable toolbar with formatting actions, link editing, and extensible item groups.
EditorSuggestionMenu: A command menu (/) to insert headings, lists, code blocks, images, and more.
EditorMentionMenu: A mention menu (@) to reference users or other entities.
EditorEmojiMenu: An emoji picker (:) to insert emojis inline.
EditorDragHandle: A drag handle to reorder blocks with a dropdown menu for block actions.
The Editor is fully extensible through TipTap's extension system and exposes the editor instance for advanced use cases.
We've also released a new Editor template that showcases all the Editor components in a production-ready setup with real-time collaboration via PartyKit and AI autocompletion using AI SDK and Vercel AI Gateway.
You can now use Tailwind CSS's prefix option (#5341) to prefix all utilities generated by Nuxt UI and avoid conflicts with your own styles or other libraries.
Exposed refs now consistently return the HTML element directly instead of the component instance. This affects InputMenu, InputNumber, InputTags, Select, and SelectMenu.
<script setup lang="ts">
const inputMenu = useTemplateRef('inputMenu')
- inputMenu.value.inputRef.$el // Component instance
+ inputMenu.value.inputRef // HTML element directly
</script>
module: properly export composables from module (cb25902)
There was an issue with how composables were exported, you no longer need the .js extension:
<script setup lang="ts">
- import { useToast } from '@nuxt/ui/composables/useToast.js'
+ import { useToast } from '@nuxt/ui/composables/useToast'
// or
+ import { useToast } from '@nuxt/ui/composables'
</script>
The Vite plugin now properly generates theme files as real files instead of incorrectly shipping them inside .nuxt/ on NPM. This ensures the #build/ui.css import and custom theme configuration work correctly.
When using the Vite plugin, update your tsconfig.node.json alias:
Enable the new experimental.componentDetection option in your nuxt.config.ts to automatically detect which components are actually used and only generate the necessary CSS for those components including their dependencies (#5222).
We apologize for these small breaking changes. With 110+ components in the library, we occasionally need to make corrections to maintain consistency and quality. We aim to minimize breaking changes, but sometimes they're necessary to improve the developer experience in the long run.
CommandPalette: add children-icon prop to use trailing-icon in input (#4397) (edda8a6)
The trailing-icon prop is now used for the Input, and a new children-icon prop has been added to customize the icon for child items:
We are excited to announce Nuxt UI v4, a major milestone that unifies Nuxt UI and Nuxt UI Pro into a single, fully open-source library. Following NuxtLabs joining Vercel in July, we're now able to offer 100+ production-ready components and a complete Figma Kit available for free to everyone.
The migration from v3 to v4 is designed to be smoother than previous major version transitions.
We recommend reading the migration guide for step-by-step instructions.
For Nuxt UI users
Update to @nuxt/ui@latest
For Nuxt UI Pro users
Replace @nuxt/ui-pro with @nuxt/ui in your dependencies
Update module registration from @nuxt/ui-pro to @nuxt/ui in your Nuxt config
Change configuration key from uiPro to ui in your app config
Update CSS imports from @nuxt/ui-pro to @nuxt/ui
Update any import statements to reference @nuxt/ui
We want to extend a special thanks to everyone who supported Nuxt UI Pro. Your early adoption and feedback were instrumental in shaping Nuxt UI. You helped us fund, maintain, and improve the project, allowing us to reach this milestone where we can now offer these powerful tools to the entire community.
A huge thanks to the dedicated team behind Nuxt UI and our incredible community of 250+ contributors. Your hard work, creativity, and passion have been the driving force behind this project's success.