Skip to content

Commit fe09402

Browse files
authored
Merge branch 'v4' into feat/wheel-picker
2 parents 3ceb2a3 + b751eae commit fe09402

129 files changed

Lines changed: 3015 additions & 1468 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/contributing/documentation.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,14 @@ links:
127127
---
128128
```
129129

130+
Optional `keywords` feed the docs search and the MCP `search-components` tool. Use alternate names from other ecosystems, not words already in the title or description:
131+
132+
```yaml
133+
keywords:
134+
- segmented control
135+
- button group
136+
```
137+
130138
For Reka UI based components, add the Reka UI link:
131139
132140
```yaml

docs/app/app.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ useHead({
1717
if (import.meta.server) {
1818
useSeoMeta({
1919
ogSiteName: 'Nuxt UI',
20+
ogType: 'website',
2021
twitterCard: 'summary_large_image'
2122
})
2223

docs/app/pages/index.vue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
164164
<USeparator />
165165

166166
<UPageSection :ui="{ container: 'lg:py-16' }" class="bg-elevated/25">
167+
<h2 class="sr-only">
168+
Features
169+
</h2>
170+
167171
<ul class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 lg:gap-8 xl:gap-y-10">
168172
<Motion
169173
v-for="(feature, index) in page?.features"
@@ -193,10 +197,10 @@ useIntersectionObserver(contributorsRef, ([entry]) => {
193197
<UIcon :name="feature.icon" class="size-5 shrink-0" />
194198
</div>
195199
<div class="flex flex-col">
196-
<h2 class="font-medium text-highlighted inline-flex items-center gap-x-1">
200+
<h3 class="font-medium text-highlighted inline-flex items-center gap-x-1">
197201
{{ feature.title }}
198202
<UIcon v-if="feature.to" :name="appConfig.ui.icons.arrowRight" class="size-4 shrink-0 opacity-0 group-hover:opacity-100 transition-all duration-200 -translate-x-1 group-hover:translate-x-0" />
199-
</h2>
203+
</h3>
200204
<p class="text-sm text-muted">
201205
{{ feature.description }}
202206
</p>

docs/content/blog/how-to-build-an-ai-chat.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Check out the [`Nuxt`](https://github.com/nuxt-ui-templates/chat) and [`Vue`](ht
3636

3737
Before we start, make sure you have:
3838

39-
- Node.js 20+ installed
39+
- Node.js 22.19+ or 24.11+ installed
4040
- A [Vercel AI Gateway](https://vercel.com/docs/ai-gateway) API key (provides access to multiple AI providers through a single endpoint)
4141

4242
## Project setup
@@ -191,7 +191,7 @@ This section covers integrating AI on the server. The following API endpoints ha
191191

192192
### Creating a chat
193193

194-
First, create the endpoint that initializes a new chat and saves the first message to the database. This uses the [`UIMessage`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/ui-message) type from the AI SDK:
194+
First, create the endpoint that initializes a new chat and saves the first message to the database. This uses the [`UIMessage`](https://ai-sdk.dev/docs/reference/ai-sdk-core/ui-message) type from the AI SDK:
195195

196196
::code-tree-intersection
197197
```ts [server/api/chats.post.ts]
@@ -404,7 +404,7 @@ export default defineEventHandler(async (event) => {
404404
```
405405
::
406406

407-
## Wire up the UI
407+
## Wiring up the UI
408408

409409
Nuxt UI provides purpose-built components for AI chat interfaces: [`UChatPrompt`](/docs/components/chat-prompt) for the input area and [`UChatMessages`](/docs/components/chat-messages) for displaying the conversation.
410410

@@ -509,7 +509,7 @@ html.dark .shiki span {
509509

510510
## Creating the chat page
511511

512-
The chat page is where the actual conversation happens. It integrates the AI SDK's [`Chat`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/chat) class and [`DefaultChatTransport`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/default-chat-transport) for real-time streaming.
512+
The chat page is where the actual conversation happens. It integrates the AI SDK's [`useChat`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat) composable and [`DefaultChatTransport`](https://ai-sdk.dev/docs/ai-sdk-ui/transport#default-transport) for real-time streaming.
513513

514514
::code-tree-intersection
515515
:::code-collapse
@@ -532,7 +532,7 @@ if (!chatData.value) {
532532
533533
const input = ref('')
534534
535-
// Initialize the Chat class from AI SDK
535+
// Initialize the useChat composable from AI SDK
536536
const { messages, status, error, sendMessage, regenerate, stop } = useChat({
537537
id: chatData.value.id,
538538
messages: chatData.value.messages,
@@ -632,7 +632,7 @@ onMounted(() => {
632632

633633
Here's a breakdown of the key parts:
634634

635-
**The Chat Class**
635+
**The `useChat` composable**
636636

637637
The [`useChat`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat) composable from `@ai-sdk/vue` manages the entire conversation state. It handles:
638638
- Message history with `messages`
@@ -641,7 +641,7 @@ The [`useChat`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat) composable
641641
- Stopping generation with `stop()`
642642
- Regenerating responses with `regenerate()`
643643

644-
The `onData` callback receives [custom data events](https://ai-sdk.dev/docs/ai-sdk-ui/streaming-data) from the server (like `data-chat-title`), allowing you to react to server-side events during streaming.
644+
The `onData` callback receives [custom data events](https://ai-sdk.dev/docs/ai-sdk-ui/streaming-data) from the server (like `data-chat-title`), so you can react to server-side events during streaming.
645645

646646
**UChatMessages Component**
647647

@@ -810,7 +810,7 @@ if (!chatData.value) {
810810
811811
const input = ref('')
812812
813-
// Initialize the Chat class from AI SDK
813+
// Initialize the useChat composable from AI SDK
814814
const { messages, status, error, sendMessage, regenerate, stop } = useChat({
815815
id: chatData.value.id,
816816
messages: chatData.value.messages,
@@ -1141,7 +1141,9 @@ Then, in the Vercel dashboard:
11411141
- Enable **AI Gateway** and add credits so requests can be processed.
11421142
- Add a **Turso** database from the Vercel Marketplace and connect it to your project (it will provision the database and add the required environment variables automatically).
11431143

1144-
> Note: On Vercel, you **don’t need to manually add `AI_GATEWAY_API_KEY`** — Vercel handles the gateway configuration for deployments. Keep using `.env` locally for development.
1144+
::note
1145+
On Vercel you don't need to manually add `AI_GATEWAY_API_KEY`. Vercel handles the gateway configuration for deployments. Keep using `.env` locally for development.
1146+
::
11451147

11461148
::note{to="https://vercel.com/docs/ai-gateway" target="_blank"}
11471149
Learn more about setting up AI Gateway in the **Vercel AI Gateway documentation**.
@@ -1161,7 +1163,7 @@ The combination of Nuxt's full-stack capabilities, Nuxt UI's purpose-built chat
11611163

11621164
**Resources:**
11631165

1164-
- [Nuxt UI Chat Components](https://ui.nuxt.com/components/chat)
1166+
- [Nuxt UI Chat Components](https://ui.nuxt.com/docs/components/chat)
11651167
- [NuxtHub Database](https://hub.nuxt.com/docs/features/database)
11661168
- [AI SDK Documentation](https://ai-sdk.dev)
11671169
- [AI Gateway Documentation](https://vercel.com/docs/ai-gateway)

docs/content/community.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ items:
2626
to: 'https://www.raycast.com/HugoRCD/nuxt'
2727
target: '_blank'
2828
user:
29-
name: 'HugoRDC'
29+
name: 'HugoRCD'
3030
to: 'https://github.com/HugoRCD'
3131
target: '_blank'
3232
avatar:

docs/content/docs/1.getting-started/1.index.md

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ If you are migrating from v2, you can read more in this **migration guide**.
5858

5959
## Core technologies
6060

61+
Nuxt UI is built on three foundations: Reka UI for behavior and accessibility, Tailwind CSS for styling, and Tailwind Variants for composing variants.
62+
6163
### Reka UI
6264

6365
Nuxt UI is built on top of [Reka UI](https://reka-ui.com/) as a foundation for the components:
@@ -88,13 +90,25 @@ Nuxt UI takes advantage of [Tailwind Variants](https://www.tailwind-variants.org
8890

8991
### Ecosystem integration
9092

91-
Nuxt UI is SSR compatible and integrates seamlessly with the Nuxt ecosystem (these features also work in Vue with additional configuration):
93+
Nuxt UI is SSR compatible and integrates seamlessly with the ecosystem:
9294

93-
- [**Icons**](/docs/getting-started/integrations/icons): Access 200,000+ icons from Iconify
95+
::framework-only
96+
#nuxt
97+
:::div
98+
- [**Icons**](/docs/getting-started/integrations/icons/nuxt): Access 200,000+ icons from Iconify
9499
- [**Fonts**](/docs/getting-started/integrations/fonts): Plug-and-play web font optimization and configuration
95-
- [**Color Mode**](/docs/getting-started/integrations/color-mode): Dark and Light mode with auto detection
96-
- [**i18n**](/docs/getting-started/integrations/i18n): Internationalize your components with 50+ languages
100+
- [**Color Mode**](/docs/getting-started/integrations/color-mode/nuxt): Dark and Light mode with auto detection
101+
- [**i18n**](/docs/getting-started/integrations/i18n/nuxt): Internationalize your components with 50+ languages
97102
- [**Content**](/docs/getting-started/integrations/content): Beautiful typography out of the box
103+
:::
104+
105+
#vue
106+
:::div
107+
- [**Icons**](/docs/getting-started/integrations/icons/vue): Access 200,000+ icons from Iconify
108+
- [**Color Mode**](/docs/getting-started/integrations/color-mode/vue): Dark and Light mode with auto detection
109+
- [**i18n**](/docs/getting-started/integrations/i18n/vue): Internationalize your components with 50+ languages
110+
:::
111+
::
98112

99113
### Vue compatibility (Nuxt optional)
100114

docs/content/docs/1.getting-started/2.installation/1.nuxt.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ It's recommended to install the [Tailwind CSS IntelliSense](https://marketplace.
104104
```
105105

106106
::note{to="/docs/components/app"}
107-
The `App` component provides global configurations and is required for **Toast**, **Tooltip** components to work as well as **Programmatic Overlays**.
107+
The `App` component sets up global config and is required for **Toast**, **Tooltip** and **programmatic overlays**.
108108
::
109109

110110
::
@@ -394,6 +394,8 @@ This strips **structural** classes too (positioning, transitions, flex/grid), no
394394

395395
Use the `theme.defaultVariants` option to override the default `color` and `size` variants for components.
396396

397+
Only defaults that are exactly `primary` or `md` are replaced, so Avatar keeps `color: 'neutral'` and Separator keeps `size: 'xs'`.
398+
397399
- Default: `{ color: 'primary', size: 'md' }`{lang="ts-type"}
398400

399401
```ts [nuxt.config.ts] {4-11}
@@ -491,7 +493,7 @@ Use the [`prose`](#prose) option instead.
491493

492494
### `content`
493495

494-
Use the `content` option to force the import of Nuxt UI `<Prose>` and `<UContent>` components even if `@nuxt/content` is not installed.
496+
Use the `content` option to force the import of the Nuxt UI prose and content components even if `@nuxt/content` is not installed.
495497

496498
- Default: `false`{lang="ts-type"}
497499

docs/content/docs/1.getting-started/2.installation/2.vue.md

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ These declaration files are only written when Vite runs. The default `create-vue
140140
::
141141

142142
::tip
143-
Internally, Nuxt UI relies on custom alias to resolve the theme types. If you're using TypeScript, you should add an alias to your `tsconfig` to enable auto-completion in your `vite.config.ts`.
143+
Internally, Nuxt UI relies on custom aliases to resolve the theme types. If you're using TypeScript, add these aliases to your `tsconfig` files to enable auto-completion in your `vite.config.ts`.
144144

145145
```json [tsconfig.node.json]
146146
{
@@ -268,7 +268,7 @@ Import the CSS file in your entrypoint.
268268

269269
:::code-group{sync="vite"}
270270

271-
```ts [src/main.ts]{1}
271+
```ts [src/main.ts (Vite)]{1}
272272
import './assets/css/main.css'
273273

274274
import { createApp } from 'vue'
@@ -560,7 +560,7 @@ export default defineConfig({
560560

561561
### `ui`
562562

563-
Use the `ui` option to provide configuration for Nuxt UI.
563+
Use the `ui` option to provide configuration for Nuxt UI. This is the Vue equivalent of the `ui` key in Nuxt's `app.config.ts`.
564564

565565
```ts [vite.config.ts] {9-14}
566566
import { defineConfig } from 'vite'
@@ -582,6 +582,57 @@ export default defineConfig({
582582
})
583583
```
584584

585+
### `dts`
586+
587+
Use the `dts` option to enable or disable the generation of declaration files for auto-imported components and composables.
588+
589+
- Default: `true`{lang="ts-type"}
590+
591+
```ts [vite.config.ts] {9}
592+
import { defineConfig } from 'vite'
593+
import vue from '@vitejs/plugin-vue'
594+
import ui from '@nuxt/ui/vite'
595+
596+
export default defineConfig({
597+
plugins: [
598+
vue(),
599+
ui({
600+
dts: false
601+
})
602+
]
603+
})
604+
```
605+
606+
### `icon`
607+
608+
Use the `icon` option to set default props for the [Icon](/docs/components/icon) component (`size`, `mode`, `customize`) and to configure build-time icon bundling through `clientBundle`. Bundling of Nuxt UI's own icons is enabled by default when their collection is installed. Set `clientBundle: false` to opt out.
609+
610+
- Default: `{}`{lang="ts-type"}
611+
612+
```ts [vite.config.ts] {9-14}
613+
import { defineConfig } from 'vite'
614+
import vue from '@vitejs/plugin-vue'
615+
import ui from '@nuxt/ui/vite'
616+
617+
export default defineConfig({
618+
plugins: [
619+
vue(),
620+
ui({
621+
icon: {
622+
mode: 'svg',
623+
clientBundle: {
624+
scan: true
625+
}
626+
}
627+
})
628+
]
629+
})
630+
```
631+
632+
::note{to="/docs/getting-started/integrations/icons/vue#collections"}
633+
Learn more about icon collections and client bundling in the **Icons** documentation.
634+
::
635+
585636
### `colorMode`
586637

587638
Use the `colorMode` option to enable or disable the color mode integration from `@vueuse/core`.
@@ -692,6 +743,8 @@ This strips **structural** classes too (positioning, transitions, flex/grid), no
692743

693744
Use the `theme.defaultVariants` option to override the default `color` and `size` variants for components.
694745

746+
Only defaults that are exactly `primary` or `md` are replaced, so Avatar keeps `color: 'neutral'` and Separator keeps `size: 'xs'`.
747+
695748
- Default: `{ color: 'primary', size: 'md' }`{lang="ts-type"}
696749

697750
```ts [vite.config.ts] {9-14}

docs/content/docs/1.getting-started/3.migration/1.v4.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ links:
1212
Nuxt UI v4 marks a major milestone: **Nuxt UI and Nuxt UI Pro are now unified into a single, fully open-source and free library**. You now have access to 125+ production-ready components, all available in the `@nuxt/ui` package.
1313

1414
::note
15-
Nuxt UI v4 requires **Nuxt 4** due to some dependencies. Make sure to upgrade to Nuxt 4 before migrating to Nuxt UI v4.
15+
Nuxt UI v4 requires **Nuxt 4.1 or later** due to some dependencies. Make sure to upgrade before migrating to Nuxt UI v4.
1616
::
1717

1818
This guide provides step-by-step instructions to migrate your application from v3 to v4.
@@ -387,7 +387,7 @@ export default defineNuxtConfig({
387387
```
388388
::
389389

390-
2. The `useChat` composable API changed `input` and `handleSubmit` were removed in favor of `sendMessage`, and `messages` is now a ref you set directly:
390+
2. The `useChat` composable API changed: `input` and `handleSubmit` were removed in favor of `sendMessage`, and `messages` is now a ref you set directly:
391391

392392
```diff
393393
<script setup lang="ts">

docs/content/docs/1.getting-started/3.migration/2.v3.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,8 @@ const groups = [{
735735

736736
### Changed composables
737737

738+
Some composables changed their signature or the names of their options:
739+
738740
- The `useToast()` composable `timeout` prop has been renamed to `duration`:
739741

740742
```diff
@@ -807,7 +809,7 @@ import { ModalExampleComponent } from '#components'
807809
- })
808810
- }
809811
+ async function openModal() {
810-
+ const instance = modal.open(ModalExampleComponent, {
812+
+ const instance = modal.open({
811813
+ count: count.value
812814
+ })
813815
+
@@ -822,6 +824,8 @@ import { ModalExampleComponent } from '#components'
822824

823825
### Changed form validation
824826

827+
Form errors changed shape, so any code reading them needs updating:
828+
825829
- The error object property for targeting form fields has been renamed from `path` to `name`:
826830

827831
```diff

0 commit comments

Comments
 (0)