ChatPromptSubmit

ButtonGitHub
A Button for submitting chat prompts with automatic status handling.

Usage

The ChatPromptSubmit component is used inside the ChatPrompt component to submit the prompt. It automatically handles the different status values to control the chat.

It extends the Button component, so you can pass any property such as color, variant, size, etc.

<template>
  <UChatPrompt>
    <UChatPromptSubmit />
  </UChatPrompt>
</template>
You can also use it inside the footer slot of the ChatPrompt component.

Ready

When its status is ready, use the color, variant and icon props to customize the Button. Defaults to:

  • color="primary"
  • variant="solid"
  • icon="i-lucide-arrow-up"
<template>
  <UChatPromptSubmit color="primary" variant="solid" icon="i-lucide-arrow-up" />
</template>
You can customize this icon globally in your app.config.ts under ui.icons.arrowUp key.
You can customize this icon globally in your vite.config.ts under ui.icons.arrowUp key.

Submitted

When its status is submitted, use the submitted-color, submitted-variant and submitted-icon props to customize the Button. Defaults to:

  • submittedColor="neutral"
  • submittedVariant="subtle"
  • submittedIcon="i-lucide-square"
The stop event is emitted when the user clicks on the Button.
<template>
  <UChatPromptSubmit
    submitted-color="neutral"
    submitted-variant="subtle"
    submitted-icon="i-lucide-square"
    status="submitted"
  />
</template>
You can customize this icon globally in your app.config.ts under ui.icons.stop key.
You can customize this icon globally in your vite.config.ts under ui.icons.stop key.

Streaming

When its status is streaming, use the streaming-color, streaming-variant and streaming-icon props to customize the Button. Defaults to:

  • streamingColor="neutral"
  • streamingVariant="subtle"
  • streamingIcon="i-lucide-square"
The stop event is emitted when the user clicks on the Button.
<template>
  <UChatPromptSubmit
    streaming-color="neutral"
    streaming-variant="subtle"
    streaming-icon="i-lucide-square"
    status="streaming"
  />
</template>
You can customize this icon globally in your app.config.ts under ui.icons.stop key.
You can customize this icon globally in your vite.config.ts under ui.icons.stop key.

Error

When its status is error, use the error-color, error-variant and error-icon props to customize the Button. Defaults to:

  • errorColor="error"
  • errorVariant="soft"
  • errorIcon="i-lucide-rotate-ccw"
The reload event is emitted when the user clicks on the Button.
<template>
  <UChatPromptSubmit
    error-color="error"
    error-variant="soft"
    error-icon="i-lucide-rotate-ccw"
    status="error"
  />
</template>
You can customize this icon globally in your app.config.ts under ui.icons.reload key.
You can customize this icon globally in your vite.config.ts under ui.icons.reload key.

Examples

These chat components are designed to be used with the AI SDK v5 from Vercel AI SDK.
Check out the source code of our AI Chat template on GitHub for a real-life example.

Within a page

Use the ChatPromptSubmit component with the Chat class from AI SDK v5 to display a chat prompt within a page.

Pass the status prop and listen to the stop and reload events to control the chat.

pages/[id].vue
<script setup lang="ts">
import { Chat } from '@ai-sdk/vue'
import { getTextFromMessage } from '@nuxt/ui/utils/ai'

const input = ref('')

const chat = new Chat({
  onError(error) {
    console.error(error)
  }
})

function onSubmit() {
  chat.sendMessage({ text: input.value })

  input.value = ''
}
</script>

<template>
  <UDashboardPanel>
    <template #body>
      <UContainer>
        <UChatMessages :messages="chat.messages" :status="chat.status">
          <template #content="{ message }">
            <MDC :value="getTextFromMessage(message)" :cache-key="message.id" class="*:first:mt-0 *:last:mb-0" />
          </template>
        </UChatMessages>
      </UContainer>
    </template>

    <template #footer>
      <UContainer class="pb-4 sm:pb-6">
        <UChatPrompt v-model="input" :error="chat.error" @submit="onSubmit">
          <UChatPromptSubmit :status="chat.status" @stop="chat.stop" @reload="chat.regenerate" />
        </UChatPrompt>
      </UContainer>
    </template>
  </UDashboardPanel>
</template>

API

Props

Prop Default Type
as

any

The element or component this component should render as when not a link.

status

'ready'

"error" | "submitted" | "streaming" | "ready"

icon

appConfig.ui.icons.arrowUp

string | object

The icon displayed in the button when the status is ready.

color

'primary'

The color of the button when the status is ready.

variant

'solid'

The variant of the button when the status is ready.

streamingIcon

string | object

The icon displayed in the button when the status is streaming.

streamingColor

The color of the button when the status is streaming.

streamingVariant

The variant of the button when the status is streaming.

submittedIcon

appConfig.ui.icons.stop

string | object

The icon displayed in the button when the status is submitted.

submittedColor

'neutral'

The color of the button when the status is submitted.

submittedVariant

'subtle'

The variant of the button when the status is submitted.

errorIcon

appConfig.ui.icons.reload

string | object

The icon displayed in the button when the status is error.

errorColor

'error'

The color of the button when the status is error.

errorVariant

'soft'

The variant of the button when the status is error.

type

'button'

"reset" | "submit" | "button"

The type of the button when not a link.

to

string | RouteLocationAsRelativeGeneric | RouteLocationAsPathGeneric

Route Location the link should navigate to when clicked on.

target

null | "_blank" | "_parent" | "_self" | "_top" | string & {}

Where to display the linked URL, as the name for a browsing context.

trailingSlash

"append" | "remove"

An option to either add or remove trailing slashes in the href for this specific link. Overrides the global trailingSlash option if provided.

autofocus
disabled

boolean

form

string

formaction

string

formenctype

string

formmethod

string

formnovalidate

false | true | "true" | "false"

formtarget

string

name

string

value

string | number | readonly string[]

download

any

hreflang

string

media

string

ping

string

referrerpolicy

"" | "no-referrer" | "no-referrer-when-downgrade" | "origin" | "origin-when-cross-origin" | "same-origin" | "strict-origin" | "strict-origin-when-cross-origin" | "unsafe-url"

active

boolean

Force the link to be active independent of the current route.

label

string

activeColor

"error" | "primary" | "secondary" | "success" | "info" | "warning" | "neutral"

activeVariant

"solid" | "outline" | "soft" | "subtle" | "ghost" | "link"

size

'md'

"md" | "xs" | "sm" | "lg" | "xl"

square

boolean

Render the button with equal padding on all sides.

block

boolean

Render the button full width.

loadingAuto

boolean

Set loading state automatically based on the @click promise state

avatar

AvatarProps

Display an avatar on the left side.

leading

boolean

When true, the icon will be displayed on the left side.

leadingIcon

string | object

Display an icon on the left side.

trailing

boolean

When true, the icon will be displayed on the right side.

trailingIcon

string | object

Display an icon on the right side.

loading

boolean

When true, the loading icon will be displayed.

loadingIcon

appConfig.ui.icons.loading

string | object

The icon when the loading prop is true.

ui

{ base?: ClassNameValue; } & { base?: ClassNameValue; label?: ClassNameValue; leadingIcon?: ClassNameValue; leadingAvatar?: ClassNameValue; leadingAvatarSize?: ClassNameValue; trailingIcon?: ClassNameValue; }

This component also supports all native <button> HTML attributes.

Slots

Slot Type
leading

{ ui: object; }

default

{ ui: object; }

trailing

{ ui: object; }

Emits

Event Type
stop
reload

[]

Theme

app.config.ts
export default defineAppConfig({
  ui: {
    chatPromptSubmit: {
      slots: {
        base: ''
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        chatPromptSubmit: {
          slots: {
            base: ''
          }
        }
      }
    })
  ]
})

Changelog

61b60 — feat: allow passing a component instead of a name (#4766)

de782 — feat!: upgrade ai-sdk to v5 (#4698)

5cb65 — feat: import @nuxt/ui-pro components