Skip to content

Commit cd45c60

Browse files
chore(deps): upgrade to @nuxt/ui v4 (#50)
Co-authored-by: Benjamin Canac <[email protected]>
1 parent 5c1c51a commit cd45c60

25 files changed

+1483
-2234
lines changed

.env.example

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
# Production license for @nuxt/ui-pro, get one at https://ui.nuxt.com/pro/purchase
2-
NUXT_UI_PRO_LICENSE=
31
# Password for nuxt-auth-utils (minimum 32 characters)
42
NUXT_SESSION_PASSWORD=
5-
# Optional, Cloudflare AI Gateway ID
6-
NUXT_CLOUDFLARE_GATEWAY_ID=
73
# GitHub OAuth client ID
84
NUXT_OAUTH_GITHUB_CLIENT_ID=
95
# GitHub OAuth client secret
10-
NUXT_OAUTH_GITHUB_CLIENT_SECRET=
6+
NUXT_OAUTH_GITHUB_CLIENT_SECRET=
7+
# Vercel AI gateway key
8+
AI_GATEWAY_API_KEY=
9+
# Postgres database url
10+
DATABASE_URL=

.github/workflows/nuxthub.yml

Lines changed: 0 additions & 34 deletions
This file was deleted.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@ logs
2525

2626
# VSC
2727
.history
28+
.vercel
29+
.env*.local

README.md

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,38 @@
11
# Nuxt AI Chatbot Template
22

3-
[![Nuxt UI Pro](https://img.shields.io/badge/Made%20with-Nuxt%20UI%20Pro-00DC82?logo=nuxt&labelColor=020420)](https://ui.nuxt.com/pro)
4-
[![Deploy to NuxtHub](https://img.shields.io/badge/Deploy%20to-NuxtHub-00DC82?logo=nuxt&labelColor=020420)](https://hub.nuxt.com/new?repo=nuxt-ui-pro/chat)
3+
[![Nuxt UI](https://img.shields.io/badge/Made%20with-Nuxt%20UI-00DC82?logo=nuxt&labelColor=020420)](https://ui.nuxt.com)
54

6-
Full-featured AI Chatbot Nuxt application with authentication, chat history, multiple pages, collapsible sidebar, keyboard shortcuts, light & dark mode, command palette and more. Built using [Nuxt UI Pro](https://ui.nuxt.com/pro) components and integrated with [Workers AI](https://ai.cloudflare.com) for a complete chat experience.
5+
Full-featured AI Chatbot Nuxt application with authentication, chat history, multiple pages, collapsible sidebar, keyboard shortcuts, light & dark mode, command palette and more. Built using [Nuxt UI](https://ui.nuxt.com) components and integrated with [AI SDK v5](https://sdk.vercel.ai) for a complete chat experience.
76

87
- [Live demo](https://chat-template.nuxt.dev/)
9-
- [Documentation](https://ui.nuxt.com/getting-started/installation/pro/nuxt)
8+
- [Documentation](https://ui4.nuxt.com/docs/getting-started/installation/nuxt)
109

1110
<a href="https://chat-template.nuxt.dev/" target="_blank">
1211
<picture>
13-
<source media="(prefers-color-scheme: dark)" srcset="https://assets.hub.nuxt.com/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczovL2NoYXQtdGVtcGxhdGUubnV4dC5kZXYiLCJpYXQiOjE3NDI4NDY2ODB9.n4YCsoNz8xatox7UMoYZFNo7iS1mC_DT0h0A9cKRoTw.jpg?theme=dark">
14-
<source media="(prefers-color-scheme: light)" srcset="https://assets.hub.nuxt.com/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczovL2NoYXQtdGVtcGxhdGUubnV4dC5kZXYiLCJpYXQiOjE3NDI4NDY2ODB9.n4YCsoNz8xatox7UMoYZFNo7iS1mC_DT0h0A9cKRoTw.jpg?theme=light">
15-
<img alt="Nuxt AI Chatbot Template" src="https://assets.hub.nuxt.com/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczovL2NoYXQtdGVtcGxhdGUubnV4dC5kZXYiLCJpYXQiOjE3NDI4NDY2ODB9.n4YCsoNz8xatox7UMoYZFNo7iS1mC_DT0h0A9cKRoTw.jpg">
12+
<source media="(prefers-color-scheme: dark)" srcset="https://ui4.nuxt.com/assets/templates/nuxt/chat-dark.png">
13+
<source media="(prefers-color-scheme: light)" srcset="https://ui4.nuxt.com/assets/templates/nuxt/chat-light.png">
14+
<img alt="Nuxt AI Chatbot Template" src="https://ui4.nuxt.com/assets/templates/nuxt/chat-light.png">
1615
</picture>
1716
</a>
1817

1918
## Features
2019

21-
- ⚡️ **Streaming AI messages** powered by the [Vercel AI SDK ](https://sdk.vercel.ai)
22-
- 🤖 **Multiple model support** via [Workers AI](https://ai.cloudflare.com) with support for [AI Gateway](https://developers.cloudflare.com/ai-gateway/)
20+
- ⚡️ **Streaming AI messages** powered by the [AI SDK v5](https://sdk.vercel.ai)
21+
- 🤖 **Multiple model support** via various AI providers with built-in AI Gateway support
2322
- 🔐 **Authentication** via [nuxt-auth-utils](https://github.com/atinux/nuxt-auth-utils)
24-
- 💾 **Chat history persistence** using [NuxtHub database](https://hub.nuxt.com/docs/features/database) and [Drizzle ORM](https://orm.drizzle.team)
25-
- 🚀 **One-click deploy** to your Cloudflare account with NuxtHub: [deploy now](https://hub.nuxt.com/new?repo=nuxt-ui-pro/chat)
23+
- 💾 **Chat history persistence** using PostgreSQL database and [Drizzle ORM](https://orm.drizzle.team)
24+
- 🚀 **Easy deploy** to Vercel with zero configuration
2625

2726
## Quick Start
2827

2928
```bash
30-
npx nuxi@latest init -t github:nuxt-ui-pro/chat
29+
npx nuxi@latest init -t github:nuxt-ui-templates/chat
3130
```
3231

32+
## Deploy your own
33+
34+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fnuxt-ui-templates%2Fchat&env=NUXT_SESSION_PASSWORD,NUXT_OAUTH_GITHUB_CLIENT_ID,NUXT_OAUTH_GITHUB_CLIENT_SECRET,DATABASE_URL&demo-url=https%3A%2F%2Fchat-template.nuxt.dev%2F)
35+
3336
## Setup
3437

3538
Make sure to install the dependencies:
@@ -38,20 +41,29 @@ Make sure to install the dependencies:
3841
pnpm install
3942
```
4043

41-
Next, link a NuxtHub project (even if not deployed) to access AI models in development:
44+
Set up your environment variables by creating a `.env` file:
4245

43-
```bash
44-
npx nuxthub link
46+
```env
47+
# Database
48+
DATABASE_URL=<your-postgresql-database-url>
49+
50+
# GitHub OAuth (optional, for authentication)
51+
NUXT_OAUTH_GITHUB_CLIENT_ID=<your-github-oauth-app-client-id>
52+
NUXT_OAUTH_GITHUB_CLIENT_SECRET=<your-github-oauth-app-client-secret>
53+
54+
# AI Configuration via Vercel AI Gateway (unified API for all providers)
55+
AI_GATEWAY_API_KEY=<your-vercel-ai-gateway-api-key>
4556
```
4657

4758
> [!TIP]
48-
> It works with free Cloudflare and NuxtHub accounts.
59+
> With [Vercel AI Gateway](https://vercel.com/docs/ai-gateway), you don't need individual API keys for OpenAI, Anthropic, etc. The AI Gateway provides a unified API to access hundreds of models through a single endpoint with automatic load balancing, fallbacks, and spend monitoring.
4960
50-
To add authentication with GitHub, you need to [create a GitHub OAuth application](https://github.com/settings/applications/new) and then fill the credentials in your `.env`:
61+
To add authentication with GitHub, you need to [create a GitHub OAuth application](https://github.com/settings/applications/new).
5162

52-
```env
53-
NUXT_OAUTH_GITHUB_CLIENT_ID=<your-github-oauth-app-client-id>
54-
NUXT_OAUTH_GITHUB_CLIENT_SECRET=<your-github-oauth-app-client-secret>
63+
Run database migrations:
64+
65+
```bash
66+
pnpm db:migrate
5567
```
5668

5769
## Development
@@ -70,25 +82,45 @@ Build the application for production:
7082
pnpm build
7183
```
7284

73-
> [!IMPORTANT]
74-
> Make sure to add your [Nuxt UI Pro License](https://ui.nuxt.com/getting-started/license) in order to build for production
75-
7685
Locally preview production build:
7786

7887
```bash
7988
pnpm preview
8089
```
8190

82-
Deploy to your Cloudflare account with zero configuration:
91+
Deploy to Vercel:
8392

8493
```bash
85-
npx nuxthub deploy
94+
npx vercel
8695
```
8796

97+
Or connect your repository to Vercel for automatic deployments:
98+
99+
1. Push your code to GitHub
100+
2. Connect your repository to [Vercel](https://vercel.com)
101+
3. Configure your environment variables in the Vercel dashboard
102+
4. Deploy automatically on every push
103+
88104
> [!NOTE]
89-
> NuxtHub will automatically spawn a D1 database and apply the database migrations when deploying your project.
105+
> Make sure to configure your PostgreSQL database connection and run migrations in your production environment.
106+
107+
The application is configured to use [Vercel AI Gateway](https://vercel.com/docs/ai-gateway) which provides:
108+
109+
- **Unified API**: Access hundreds of AI models through a single endpoint
110+
- **High Reliability**: Automatic retries and fallbacks between providers
111+
- **Spend Monitoring**: Track usage and set budgets across all providers
112+
- **Load Balancing**: Distribute requests for optimal performance
113+
114+
Simply configure your `AI_GATEWAY_API_KEY` in your Vercel environment variables for production use.
115+
116+
## AI Gateway Setup
117+
118+
1. Create a Vercel account at [vercel.com](https://vercel.com)
119+
2. Navigate to your [AI Gateway settings](https://vercel.com/dashboard/ai-gateway)
120+
3. Generate an API key for your project
121+
4. Add the key to your environment variables as `AI_GATEWAY_API_KEY`
90122

91-
Optionally, you can create a [Cloudflare AI Gateway](https://developers.cloudflare.com/ai-gateway/) to have usage analytics and the ability to cache response to reduce costs. Once created, you can add the `NUXT_CLOUDFLARE_GATEWAY_ID` environment variable with the named of your gateway.
123+
The AI Gateway automatically handles authentication with all supported AI providers including OpenAI, Anthropic, Google, xAI, and many others.
92124

93125
## Renovate integration
94126

app/app.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ useHead({
1818
})
1919
2020
const title = 'Nuxt AI Chatbot template'
21-
const description = 'A full-featured, hackable Nuxt AI chatbot template made with Nuxt UI Pro.'
21+
const description = 'A full-featured, hackable Nuxt AI chatbot template made with Nuxt UI.'
2222
2323
useSeoMeta({
2424
title,
2525
description,
2626
ogTitle: title,
2727
ogDescription: description,
28-
ogImage: 'https://assets.hub.nuxt.com/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczovL2NoYXQtdGVtcGxhdGUubnV4dC5kZXYiLCJpYXQiOjE3NDI4NDY2ODB9.n4YCsoNz8xatox7UMoYZFNo7iS1mC_DT0h0A9cKRoTw.jpg?theme=light',
29-
twitterImage: 'https://assets.hub.nuxt.com/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczovL2NoYXQtdGVtcGxhdGUubnV4dC5kZXYiLCJpYXQiOjE3NDI4NDY2ODB9.n4YCsoNz8xatox7UMoYZFNo7iS1mC_DT0h0A9cKRoTw.jpg?theme=light',
28+
ogImage: 'https://ui4.nuxt.com/assets/templates/nuxt/chat-light.png',
29+
twitterImage: 'https://ui4.nuxt.com/assets/templates/nuxt/chat-light.png',
3030
twitterCard: 'summary_large_image'
3131
})
3232
</script>

app/assets/css/main.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@import "tailwindcss" theme(static);
2-
@import "@nuxt/ui-pro";
2+
@import "@nuxt/ui";
33

44
@theme static {
55
--font-sans: 'Public Sans', sans-serif;
@@ -19,4 +19,4 @@
1919

2020
:root {
2121
--ui-container: var(--container-3xl);
22-
}
22+
}

app/components/ModelSelect.vue

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
<script setup lang="ts">
2-
const { model, models } = useLLM()
2+
const { model, models } = useModels()
3+
4+
const items = computed(() => models.map(model => ({
5+
label: model,
6+
value: model,
7+
icon: `i-simple-icons-${model.split('/')[0]}`
8+
})))
39
</script>
410

511
<template>
612
<USelectMenu
713
v-model="model"
8-
:items="models"
14+
:items="items"
15+
:icon="`i-simple-icons-${model.split('/')[0]}`"
916
variant="ghost"
17+
value-key="value"
1018
class="hover:bg-default focus:bg-default data-[state=open]:bg-default"
1119
:ui="{
1220
trailingIcon: 'group-data-[state=open]:rotate-180 transition-transform duration-200'

app/components/UserMenu.vue

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ const items = computed<DropdownMenuItem[][]>(() => ([[{
9595
icon: 'i-lucide-layout-template',
9696
children: [{
9797
label: 'Starter',
98-
to: 'https://ui-pro-starter.nuxt.dev/'
98+
to: 'https://starter-template.nuxt.dev/'
9999
}, {
100100
label: 'Landing',
101101
to: 'https://landing-template.nuxt.dev/'
@@ -113,21 +113,22 @@ const items = computed<DropdownMenuItem[][]>(() => ([[{
113113
to: 'https://chat-template.nuxt.dev/',
114114
checked: true,
115115
type: 'checkbox'
116+
}, {
117+
label: 'Portfolio',
118+
to: 'https://portfolio-template.nuxt.dev/'
119+
}, {
120+
label: 'Changelog',
121+
to: 'https://changelog-template.nuxt.dev/'
116122
}]
117123
}], [{
118124
label: 'Documentation',
119125
icon: 'i-lucide-book-open',
120-
to: 'https://ui.nuxt.com/getting-started/installation/pro/nuxt',
126+
to: 'https://ui4.nuxt.com/docs/getting-started/installation/nuxt',
121127
target: '_blank'
122128
}, {
123129
label: 'GitHub repository',
124130
icon: 'i-simple-icons-github',
125-
to: 'https://github.com/nuxt-ui-pro/chat',
126-
target: '_blank'
127-
}, {
128-
label: 'Upgrade to Pro',
129-
icon: 'i-lucide-rocket',
130-
to: 'https://ui.nuxt.com/pro/purchase',
131+
to: 'https://github.com/nuxt-ui-templates/chat',
131132
target: '_blank'
132133
}], [{
133134
label: 'Log out',

app/composables/useLLM.ts

Lines changed: 0 additions & 46 deletions
This file was deleted.

app/composables/useModels.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
export function useModels() {
2+
const models = [
3+
// OpenAI Models
4+
'openai/gpt-5',
5+
'openai/gpt-5-mini',
6+
'openai/gpt-4o',
7+
'openai/gpt-4o-mini',
8+
// Anthropic Claude Models
9+
'anthropic/claude-sonnet-4',
10+
'anthropic/claude-sonnet-3.7',
11+
// Google Gemini Models
12+
'google/gemini-2.5-pro',
13+
'google/gemini-2.5-flash'
14+
]
15+
16+
const model = useCookie<string>('model', { default: () => 'openai/gpt-4o-mini' })
17+
18+
return {
19+
models,
20+
model
21+
}
22+
}

0 commit comments

Comments
 (0)