Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Production license for @nuxt/ui-pro, get one at https://ui.nuxt.com/pro/purchase
NUXT_UI_PRO_LICENSE=
# Password for nuxt-auth-utils (minimum 32 characters)
NUXT_SESSION_PASSWORD=
# Optional, Cloudflare AI Gateway ID
NUXT_CLOUDFLARE_GATEWAY_ID=
# GitHub OAuth client ID
NUXT_OAUTH_GITHUB_CLIENT_ID=
# GitHub OAuth client secret
NUXT_OAUTH_GITHUB_CLIENT_SECRET=
NUXT_OAUTH_GITHUB_CLIENT_SECRET=
# Vercel AI gateway key
AI_GATEWAY_API_KEY=
# Postgres database url
DATABASE_URL=
34 changes: 0 additions & 34 deletions .github/workflows/nuxthub.yml

This file was deleted.

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ logs

# VSC
.history
.vercel
.env*.local
86 changes: 59 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,38 @@
# Nuxt AI Chatbot Template

[![Nuxt UI Pro](https://img.shields.io/badge/Made%20with-Nuxt%20UI%20Pro-00DC82?logo=nuxt&labelColor=020420)](https://ui.nuxt.com/pro)
[![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)
[![Nuxt UI](https://img.shields.io/badge/Made%20with-Nuxt%20UI-00DC82?logo=nuxt&labelColor=020420)](https://ui.nuxt.com)

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.
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.

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

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

## Features

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

## Quick Start

```bash
npx nuxi@latest init -t github:nuxt-ui-pro/chat
npx nuxi@latest init -t github:nuxt-ui-templates/chat
```

## Deploy your own

[![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)

## Setup

Make sure to install the dependencies:
Expand All @@ -38,20 +41,29 @@ Make sure to install the dependencies:
pnpm install
```

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

```bash
npx nuxthub link
```env
# Database
DATABASE_URL=<your-postgresql-database-url>

# GitHub OAuth (optional, for authentication)
NUXT_OAUTH_GITHUB_CLIENT_ID=<your-github-oauth-app-client-id>
NUXT_OAUTH_GITHUB_CLIENT_SECRET=<your-github-oauth-app-client-secret>

# AI Configuration via Vercel AI Gateway (unified API for all providers)
AI_GATEWAY_API_KEY=<your-vercel-ai-gateway-api-key>
```

> [!TIP]
> It works with free Cloudflare and NuxtHub accounts.
> 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.

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`:
To add authentication with GitHub, you need to [create a GitHub OAuth application](https://github.com/settings/applications/new).

```env
NUXT_OAUTH_GITHUB_CLIENT_ID=<your-github-oauth-app-client-id>
NUXT_OAUTH_GITHUB_CLIENT_SECRET=<your-github-oauth-app-client-secret>
Run database migrations:

```bash
pnpm db:migrate
```

## Development
Expand All @@ -70,25 +82,45 @@ Build the application for production:
pnpm build
```

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

Locally preview production build:

```bash
pnpm preview
```

Deploy to your Cloudflare account with zero configuration:
Deploy to Vercel:

```bash
npx nuxthub deploy
npx vercel
```

Or connect your repository to Vercel for automatic deployments:

1. Push your code to GitHub
2. Connect your repository to [Vercel](https://vercel.com)
3. Configure your environment variables in the Vercel dashboard
4. Deploy automatically on every push

> [!NOTE]
> NuxtHub will automatically spawn a D1 database and apply the database migrations when deploying your project.
> Make sure to configure your PostgreSQL database connection and run migrations in your production environment.

The application is configured to use [Vercel AI Gateway](https://vercel.com/docs/ai-gateway) which provides:

- **Unified API**: Access hundreds of AI models through a single endpoint
- **High Reliability**: Automatic retries and fallbacks between providers
- **Spend Monitoring**: Track usage and set budgets across all providers
- **Load Balancing**: Distribute requests for optimal performance

Simply configure your `AI_GATEWAY_API_KEY` in your Vercel environment variables for production use.

## AI Gateway Setup

1. Create a Vercel account at [vercel.com](https://vercel.com)
2. Navigate to your [AI Gateway settings](https://vercel.com/dashboard/ai-gateway)
3. Generate an API key for your project
4. Add the key to your environment variables as `AI_GATEWAY_API_KEY`

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.
The AI Gateway automatically handles authentication with all supported AI providers including OpenAI, Anthropic, Google, xAI, and many others.

## Renovate integration

Expand Down
6 changes: 3 additions & 3 deletions app/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ useHead({
})

const title = 'Nuxt AI Chatbot template'
const description = 'A full-featured, hackable Nuxt AI chatbot template made with Nuxt UI Pro.'
const description = 'A full-featured, hackable Nuxt AI chatbot template made with Nuxt UI.'

useSeoMeta({
title,
description,
ogTitle: title,
ogDescription: description,
ogImage: 'https://assets.hub.nuxt.com/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczovL2NoYXQtdGVtcGxhdGUubnV4dC5kZXYiLCJpYXQiOjE3NDI4NDY2ODB9.n4YCsoNz8xatox7UMoYZFNo7iS1mC_DT0h0A9cKRoTw.jpg?theme=light',
twitterImage: 'https://assets.hub.nuxt.com/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1cmwiOiJodHRwczovL2NoYXQtdGVtcGxhdGUubnV4dC5kZXYiLCJpYXQiOjE3NDI4NDY2ODB9.n4YCsoNz8xatox7UMoYZFNo7iS1mC_DT0h0A9cKRoTw.jpg?theme=light',
ogImage: 'https://ui4.nuxt.com/assets/templates/nuxt/chat-light.png',
twitterImage: 'https://ui4.nuxt.com/assets/templates/nuxt/chat-light.png',
twitterCard: 'summary_large_image'
})
</script>
Expand Down
4 changes: 2 additions & 2 deletions app/assets/css/main.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@import "tailwindcss" theme(static);
@import "@nuxt/ui-pro";
@import "@nuxt/ui";

@theme static {
--font-sans: 'Public Sans', sans-serif;
Expand All @@ -19,4 +19,4 @@

:root {
--ui-container: var(--container-3xl);
}
}
12 changes: 10 additions & 2 deletions app/components/ModelSelect.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
<script setup lang="ts">
const { model, models } = useLLM()
const { model, models } = useModels()

const items = computed(() => models.map(model => ({
label: model,
value: model,
icon: `i-simple-icons-${model.split('/')[0]}`
})))
</script>

<template>
<USelectMenu
v-model="model"
:items="models"
:items="items"
:icon="`i-simple-icons-${model.split('/')[0]}`"
variant="ghost"
value-key="value"
class="hover:bg-default focus:bg-default data-[state=open]:bg-default"
:ui="{
trailingIcon: 'group-data-[state=open]:rotate-180 transition-transform duration-200'
Expand Down
17 changes: 9 additions & 8 deletions app/components/UserMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const items = computed<DropdownMenuItem[][]>(() => ([[{
icon: 'i-lucide-layout-template',
children: [{
label: 'Starter',
to: 'https://ui-pro-starter.nuxt.dev/'
to: 'https://starter-template.nuxt.dev/'
}, {
label: 'Landing',
to: 'https://landing-template.nuxt.dev/'
Expand All @@ -113,21 +113,22 @@ const items = computed<DropdownMenuItem[][]>(() => ([[{
to: 'https://chat-template.nuxt.dev/',
checked: true,
type: 'checkbox'
}, {
label: 'Portfolio',
to: 'https://portfolio-template.nuxt.dev/'
}, {
label: 'Changelog',
to: 'https://changelog-template.nuxt.dev/'
}]
}], [{
label: 'Documentation',
icon: 'i-lucide-book-open',
to: 'https://ui.nuxt.com/getting-started/installation/pro/nuxt',
to: 'https://ui4.nuxt.com/docs/getting-started/installation/nuxt',
target: '_blank'
}, {
label: 'GitHub repository',
icon: 'i-simple-icons-github',
to: 'https://github.com/nuxt-ui-pro/chat',
target: '_blank'
}, {
label: 'Upgrade to Pro',
icon: 'i-lucide-rocket',
to: 'https://ui.nuxt.com/pro/purchase',
to: 'https://github.com/nuxt-ui-templates/chat',
target: '_blank'
}], [{
label: 'Log out',
Expand Down
46 changes: 0 additions & 46 deletions app/composables/useLLM.ts

This file was deleted.

22 changes: 22 additions & 0 deletions app/composables/useModels.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export function useModels() {
const models = [
// OpenAI Models
'openai/gpt-5',
'openai/gpt-5-mini',
'openai/gpt-4o',
'openai/gpt-4o-mini',
// Anthropic Claude Models
'anthropic/claude-sonnet-4',
'anthropic/claude-sonnet-3.7',
// Google Gemini Models
'google/gemini-2.5-pro',
'google/gemini-2.5-flash'
]

const model = useCookie<string>('model', { default: () => 'openai/gpt-4o-mini' })

return {
models,
model
}
}
Loading