Releases: nuxt/ui
v4.3.0
✨ Highlights
📝 New Editor components
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.
nuxt-ui-editor.mp4
📜 New ScrollArea component
The ScrollArea component provides a flexible scroll container with built-in virtualization support through TanStack Virtual.
CleanShot.2025-12-17.at.16.38.52.mp4
🚀 Features
- AuthForm: allow all input types (#5565) (1f9009f)
- ContextMenu/DropdownMenu: expose
subprop on content slots (#5609) (b09e6bc) - defineShortcuts: add
layoutIndependentoption (#4251) (ece0568) - Editor: new components (#5407) (38765c3)
- extractShortcuts: add
separatoroption (#5642) (4e71271) - FormField: add
orientationprop (#5632) (b74ec6e) - InputMenu/Select/SelectMenu: add
modelModifiersprop (#5559) (a92ee7b) - module: generate
@sourcefor nuxt layers (#5630) (de98a72) - ProseCodeTree: add
itemsprop (cb34ca5) - ScrollArea: new component (#5245) (effbb18)
- Slideover: add
insetprop (05bd995) - unplugin: add
routeroption to disable router (#5213) (b34cf8a) - unplugin: add
scanPackagesoption (#5510) (4e57139)
🐛 Bug Fixes
- BlogPost/ChangelogVersion/PageFeature/User: allow tab focus (47d93d3), closes #5635
- Carousel: consistent stopOnInteraction behavior (#5489) (36a7861)
- Carousel: improve dots focus styles (cc90fb8)
- ColorModeButton: improve icon class merging (2ce9af2)
- ContentSearch/DasboardSearch: set full height on mobile to prevent jump (70317e5)
- DashboardResizeHandle: allow hover over panel with
z-index(07147f1) - FormField: hide error if error prop is false (#5599) (6b7fe25)
- InputDate/InputTime: add missing field group variant (#5596) (cb3cec2)
- PageCard/PageCTA/PageSection: handle
reverseprop under lg screens (#5545) (60b430c) - ProseA/ProseCallout/ProseCard: improve focus styles (df5f8c2)
- Slider: add
aria-labelto thumb (#5313) (f99ec46) - Table: only forward necessary props (#5527) (b0b209e)
- Table: properly position pinned columns based on
size(e885b0e), closes #4721 #3927
🌐 Locales
- locale: add Basque language (#5689) (748d78f)
- locale: add English (United Kingdom) language (#5561) (b0139f0)
- locale: add Lao language (#5556) (f5f9885)
👋 New Contributors
- @AZERK0 made their first contribution in #5530
- @IO-Fire made their first contribution in #5557
- @thanet-s made their first contribution in #5556
- @iamThiagoo made their first contribution in #5598
- @olivierbourdeau made their first contribution in #5591
- @miguilimzero made their first contribution in #5512
- @lehuuphuc made their first contribution in #5601
- @dinocam1 made their first contribution in #5610
- @gunhaxxor made their first contribution in #5641
- @niusia-ua made their first contribution in #5642
- @sdsoldi made their first contribution in #5689
- @edimitchel made their first contribution in #5632
- @ISOR3X made their first contribution in #5510
- @innocenzi made their first contribution in #5213
Full Changelog: v4.2.1...v4.3.0
v4.2.1
🐛 Bug Fixes
- ChatPromptSubmit: proxy event to
stopandreloademits (#5400) 736a547 - ColorModeButton: missing icon import 5f30ccf, closes #5486
- Icon: improve
nametype (#5498) b654a77 - Link: define NuxtLinkProps instead of importing from
#app(#5491) da8daaa - Link: ensure consistency across Nuxt, Vue and Inertia a9ed10d, closes #5012
- module: put back
#build/ui.cssalias (#5499) d9aadc7
👋 New Contributors
Full Changelog: v4.2.0...v4.2.1
v4.2.0
✨ Highlights
📅 New InputDate & InputTime components
Two new components are now available to handle date and time inputs: InputDate (#5387) and InputTime (#5302).
<script setup lang="ts">
const date = ref(new CalendarDate(2022, 2, 3))
const time = ref(new Time(12, 30, 0))
</script>
<template>
<UInputDate v-model="date" />
<UInputTime v-model="time" />
</template>🎨 Tailwind CSS prefix
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.
export default defineNuxtConfig({
modules: ['@nuxt/ui'],
css: ['~/assets/css/main.css'],
ui: {
theme: {
prefix: 'tw'
}
}
})@import "tailwindcss" prefix(tw);
@import "@nuxt/ui";🚨 Breaking Changes
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:
{
"compilerOptions": {
"paths": {
"#build/ui": [
- "./node_modules/@nuxt/ui/.nuxt/ui"
+ "./node_modules/.nuxt-ui/ui"
]
}
}
}🚀 Features
- components: add
data-slotattributes (#5447) (dd81d46) - components: extend native HTML attributes (#5348) (5b17751)
- FileUpload: add
previewprop (#5443) (2af82e7) - InputDate: new component (#5387) (dabc4f8)
- InputTime: new component (#5302) (936253f)
- Modal: add
scrollableprop (#5306) (240897e) - module: add
theme.prefixoption (#5341) (7fca5d7) - Table: handle virtualizer
estimateSizeas function (ebc8568)
🐛 Bug Fixes
- AuthForm: ensure header is shown with
leadingslot (#5405) (b61127a) - AuthForm: use password input id for aria-controls (#5312) (55ea9be)
- ChatPrompt: proxy
disabledprop (a8f2156), closes #5300 - CheckboxGroup/RadioGroup/Switch: consistent disabled styles (ddd8faf), closes #5391
- ColorModeButton: use css to display color mode icon (#5394) (1d1c638)
- CommandPalette/ContentSearch: improve performances and filtering logic (#5433) (e751b37)
- components: calc virtualizer estimateSize based on item description (56ae8e7)
- components: consistent exposed refs (#5385) (fce2df4)
- components: remove
locale/dirprops proxy (#5432) (a6efa7a) - ContentNavigation/NavigationMenu/Tabs: ensure proper badge display (e5c11e6)
- ContentSearchButton/DashboardSearchButton: hide label and trailing with css when collapsed (3e72bf8)
- FileUpload: ensure native validation works with required (#5358) (eb491e1)
- Form: refine
nestedprop type handling and simplify logic (#5360) (8d5c26f) - inertia: set serverRendered dynamically to prevent SSR crash (#5396) (c0da1b2)
- Input/InputNumber/Textarea: make
modelModifiersgeneric (#5361) (5c347af) - InputMenu: prevent change event when selecting create item (418c87b), closes #4664
- Link: partial extend for
vue-routerandinertia(637ef58) - Marquee: move keyframes into global css (1e6242e)
- module: detect lazy components when using
experimental.componentDetection(5a5ac45) - module: properly export composables from module (cb25902), closes #5370
- module: scan layers when using
experimental.componentDetection(9872740), closes #5389 - NavigationMenu: hide label and trailing with css when collapsed (f004031), closes #4254
- NavigationMenu: proxy
modelValue/defaultValuein vertical orientation (cffaaaa), closes #5392 - ProseCallout: add
inline-blockclass to icon (#5317) (fc36f69) - RadioGroup: update
update:modelValueemit type (#5349) (4cb0638) - Table: apply styles to
thbased on column meta (#5418) (620defa) - types: export missing utils types (#5448) (5f0a107)
- vite: write theme templates (#5355) (411ebcc)
- vue: check
import.meta.env.SSRto supportvite-ssg(#5347) (8f38c04)
🌐 Locales
👋 New Contributors
- @GlitchDevX made their first contribution in #5317
- @onmax made their first contribution in #5346
- @rodriciru made their first contribution in #5405
- @NyllRE made their first contribution in #5410
- @usmanibrahim74 made their first contribution in #5418
- @hfersu made their first contribution in #5393
- @rudrokhanpro made their first contribution in #5448
- @y-l-g made their first contribution in #5396
- @Rolanddoda made their first contribution in #5461
Full Changelog: v4.1.0...v4.2.0
v4.1.0
✨ Highlights
📦 New Empty Component
A new Empty component is now available to display empty states when there's no content to show (#5200).
⚡️ Component Virtualization
Use the virtualize prop to enable virtualization for large datasets on CommandPalette, InputMenu, SelectMenu, Table and Tree components (#5162).
<template>
<UTable :data="data" :columns="columns" virtualize />
</template>🎯 Experimental Component Detection
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).
export default defineNuxtConfig({
modules: ['@nuxt/ui'],
css: ['~/assets/css/main.css'],
ui: {
experimental: {
componentDetection: true
}
}
})🚨 Breaking Changes
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.
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:
<template>
- <UCommandPalette :trailing-icon="i-lucide-arrow-right" />
+ <UCommandPalette :children-icon="i-lucide-arrow-right" />
</template>- Table: consistent args order in select event (9526a1b)
The @select event now passes arguments in a consistent order: (event, row) instead of (row, event):
<template>
- <UTable @select="(row, e) => {}" />
+ <UTable @select="(e, row) => {}" />
</template>🚀 Features
- Calendar: add
variantprop (#5138) (bb4f42c) - CommandPalette: add
children-iconprop to usetrailing-iconin input (#4397) (edda8a6) - CommandPalette: preserve group order in search results (#5197) (38647a2)
- components: expose
uiin slot props where used (#5207) (63c0a5f) - components: handle
descriptionin items (#5193) (70cf05f) - components: implement virtualization (#5162) (c744d6f)
- Empty: new component (#5200) (6a6de8d)
- InputNumber: handle
increment/decrementas booleans (#4805) (1858908) - module: add
experimental.componentDetectionoption (#5222) (f80474c) - Popover: add
closemethod in slots (#5176) (53c6508) - ProseImg: improve
zoomtransition (#4998) (d502c30) - Tree: add global event handlers and checkbox example (#5195) (84f87a5)
- Tree: expose
$elfor drag and drop example (#5239) (fcf6117) - Tree: provide additional slot props (#5194) (c8b01c9)
- useToast: handle
maxglobal configuration (#5068) (e4c6113)
🐛 Bug Fixes
- BlogPost/ChangelogVersion: allow any attrs in
imageprop (9632f99), closes #5276 - Breadcrumb: handle
activein items (cc8cbf3), closes #4771 - ChatMessage: ensure left side takes full width (af8c023)
- ChatMessage: only apply max-width on right side (a85b0e1)
- ChatMessage: reset top and bottom margin (8f9176c)
- ChatMessages: allow user scroll with
should-auto-scroll(#5252) (db73765) - ChatMessages: define user & assistant
uiprop type (#5234) (240bc1a) - CodeTree/Tree: restore item wrapper with
presentationrole (70aaf4a), closes #4945 - components: add missing
uiprop in prose proxy components (#5205) (d1afe90) - ContextMenu/DropdownMenu: allow item content class override (ab5032d), closes #5277
- Drawer/Modal/Slideover: remove close autofocus prevent (#5191) (8099440)
- Error/Main: render as
divinstead ofmain(2a09ac0), closes #4955 - FileUpload: handle disabling file delete button (08c30cf), closes #5249
- FileUpload: stuck focus while tabbing (#5128) (2477d44)
- FileUpload: use native img element for blob URLs preview (69906bc), closes #5121 #4824
- InputMenu/SelectMenu: enrich reusable template item prop (63074d6)
- InputMenu: ensure tag can be removed when number (028538a)
- Kbd: return original value and use
uppercaseclass (#5238) (4095c9a) - NavigationMenu: display trailing slot when badge not undefined (f24204f), closes #4670
- Table: consistent args order in select event (9526a1b)
- Table: expose
$elinstead ofrootRef(c019f8f), closes #5230 #5162
🌐 Locales
v3.3.7
v3.3.6
🐛 Bug Fixes
- App: allow global portal disabling (#5111) (43c119f)
- Carousel: ensure plugins init after client-side navigation (#5117) (0f7a1b7)
- Carousel: invert arrow keys in RTL direction (#5072) (27cb2b6)
- Drawer: prevent unwanted close when dismissible is false (#5085) (027c06a)
- Drawer: use full height/width for snapPoints (#5041) (8f21339)
- Pagination: make ellipsis non-interactive (#5081) (ab168af)
- Table: empty cell value causing hydration errors (#5069) (cd2662a)
- useKbd: update escape key from
⎋toEsc(#5076) (27aa80c)
Full Changelog: v3.3.5...v3.3.6
v4.0.1
🐛 Bug Fixes
- App: allow global portal disabling (#5111) (7659fa1)
- AuthForm: export type with proper inference for field-specific props (#5106) (344f269)
- Avatar: remove redundant
imgrole (066b8a1), closes #5044 - Carousel: ensure plugins init after client-side navigation (#5117) (21fbe63)
- Carousel: invert arrow keys in RTL direction (#5072) (fde53ee)
- ChatMessages: ensure content is render before scrolling (0db622a)
- ChatMessages: watch deep to handle streaming with
parts(ff67fa3) - components: add missing
data-orientationfor consistency (a9fe7c6) - ContentNavigation: improve path matching and recursion with
default-open(22ee075), closes #5112 - ContentSearch/DashboardSearch: proxy modal props to support fullscreen (095a0c1)
- DashboardPanel/DashboardSidebar: handle RTL mode (#5109) (fface35)
- Drawer: prevent unwanted close when dismissible is false (#5085) (2abdc21)
- Drawer: use full height/width for snapPoints (#5041) (b145768)
- locale: improve
ckbtranslations (#5079) (3ee3a5e) - locale: improve typography with ellipsis (#5052) (391f9f5)
- Pagination: make ellipsis non-interactive (#5081) (62f64cc)
- Table: empty cell value causing hydration errors (#5069) (44a38ea)
- unplugin: handle components resolution with subpath (31db8d9)
- useKbd: update escape key from
⎋toEsc(#5076) (64d1589) - vue: align
useCookiestub with nuxt's default value handling (#5089) (f531807)
👋 New Contributors
- @theoriginalstove made their first contribution in #5053
- @drevantonder made their first contribution in #5063
- @paulbarre made their first contribution in #5072
- @swarakaka made their first contribution in #5079
- @devzom made their first contribution in #5085
- @kendalled made their first contribution in #5122
Full Changelog: v4.0.0...v4.0.1
v4.0.0
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.
Read the blog post announcement: https://nuxt.com/blog/nuxt-ui-v4
✨ Highlights
🌐 Unified and Open Source
Nuxt UI v4 marks a significant milestone by merging Nuxt UI and Nuxt UI Pro into one cohesive, fully open-source library:
- 100+ components: Complete access to all components, including those previously exclusive to Pro
- Figma Kit: Professional design resources now available to everyone
- Single package: Everything unified under
@nuxt/ui
🖥️ Templates
All our previously exclusive templates for Nuxt and Vue are now available to everyone and updated to Nuxt UI v4:
- Starter: A minimal template to get started with Nuxt UI
- Landing: A modern landing page template powered by Nuxt Content
- Docs: A documentation template powered by Nuxt Content
- SaaS: A SaaS template with landing, pricing, docs and blog powered by Nuxt Content
- Dashboard: A dashboard template with multi-column layout for building sophisticated admin interfaces
- Chat: An AI chatbot template to build your own chatbot powered by Nuxt MDC and Vercel AI SDK
- Portfolio: A sleek portfolio template to showcase your work, skills and blog powered by Nuxt Content
- Changelog: A changelog template to display your repository releases notes from GitHub powered by Nuxt MDC
📚 Documentation
We've made extensive improvements to the documentation in v4 to provide a better developer experience:
- Unified location: All documentation now lives under
/docs/with automatic redirects from legacy paths - Dedicated sections: Theme and Typography now have their own organized sections
- AI-ready features: LLMs.txt endpoints and MCP Server integration for AI tools like Cursor, Windsurf, and GitHub Copilot
🌱 Migration from v3
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-prowith@nuxt/uiin your dependencies - Update module registration from
@nuxt/ui-proto@nuxt/uiin your Nuxt config - Change configuration key from
uiProtouiin your app config - Update CSS imports from
@nuxt/ui-proto@nuxt/ui - Update any import statements to reference
@nuxt/ui
🙏 Acknowledgements
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.
Thank you for being part of this journey 💚
v3.3.5
🐛 Bug Fixes
- InputMenu: ensure to pass a string to items when multiple (0031a75), closes #5018
- InputTags: add blur and focus event handlers on input (#5007) (5db2708)
- Progress: improve
status-positionwhen 0 (#4994) (e0891ea) - Tabs: use nullish coalescing on item value (a4ab796), closes #4804
- types: allow arbitrary keys in tv config (#4992) (8d859ea)
- types: resolve ambient declaration error in
iconstype (#4991) (526cb81)
New Contributors
Full Changelog: v3.3.4...v3.3.5
v4.0.0-beta.0
🐛 Bug Fixes
- ChatMessages: wrap indicator with slot (#5036) (c00bf30)
- CheckboxGroup: proxy generic to emits (ffa5b23)
- Form: improve nested form validation handling (#5024) (77a554e)
- Form: remove
joiandyupin favor of @standard-schema/spec (#5035) (723cf36) - InputMenu: ensure to pass a string to items when multiple (9beccbb), closes #5018
- InputTags: add blur and focus event handlers on input (#5007) (3fd2614)
- locale: improve translations in
ptlocale (#5003) (725ef9b) - module: only inject tailwindcss vite plugin once (#5008) (c2e39dd)
- ProseImg: add
w-fullby default (#4997) (de47add) - Tabs: use nullish coalescing on item value (340fc48), closes #4804
- Tree: remove
value-keyin favor ofget-key(#4999) (240ff42) - types: allow arbitrary keys in tv config (#4992) (ae77b69)
New Contributors
- @jd-solanki made their first contribution in #4872
- @JoniDS made their first contribution in #5003
Full Changelog: v4.0.0-alpha.2...v4.0.0-beta.0