Monza Motors includes a floating AI chat assistant that lets signed-in customers ask questions about the vehicle catalog and get instant, contextual answers. The assistant is accessible via the FloatingBar at the bottom of the page and is powered by Groq’sDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Jason-AML/MonzaSport-Nextjs/llms.txt
Use this file to discover all available pages before exploring further.
llama-3.3-70b-versatile model. Every conversation is persisted in Supabase’s messages table and delivered to the browser in real time via Supabase Realtime, so new assistant replies appear without polling or page refreshes.
How It Works
User opens the chat panel
The chat panel is part of the
FloatingBar component and is only interactive when the user is signed in. Unauthenticated visitors see a “Please sign in” prompt instead of the message input.useChat() loads history and subscribes to Realtime
When the
ChatAssistant component mounts, the useChat() hook fires. It queries the messages table for all rows matching the current user_id, ordered by created_at, and sets the initial messages state. In a parallel useEffect, it opens a Supabase Realtime channel scoped to the same user_id filter.User sends a message
When the user submits text,
sendMessage(content) first inserts the message into the messages table with role: 'user', then POSTs the user_id and content to /api/chat.API route builds context and calls Groq
The
POST /api/chat handler fetches the full vehicle catalog via getCollections() and retrieves the last 20 messages from the messages table for that user. It assembles a system prompt containing the formatted catalog data and passes the history plus the new user message to Groq’s llama-3.3-70b-versatile model using the Vercel AI SDK’s generateText helper.Assistant reply is saved to Supabase
Once Groq responds, the API route inserts the generated text into the
messages table with role: 'assistant'. The browser’s open Realtime channel immediately receives the new row via a postgres_changes event.useChat Hook
The useChat hook at src/hooks/useChat.js encapsulates all chat state, history loading, Realtime subscriptions, and message sending. It reads the authenticated user from useAuth() so it automatically becomes active the moment the user signs in.
messages— The full conversation history for the current user, sorted oldest-first. Each entry includesid,user_id,role('user'or'assistant'),content, andcreated_at.loading— Set totruewhensendMessageis in flight (from the moment the user message is inserted until the API route returns). TheChatAssistantrenders a “Your assistant is typing…” indicator while this istrue.sendMessage(text)— An async function memoised withuseCallback. It guards against empty strings and skips the call ifuserisnull.user— The Supabase user object sourced fromAuthProvider. The hook short-circuits bothuseEffecthooks whenuserisnull, so no Supabase calls are made for unauthenticated visitors.
Real-time Subscriptions
TheuseChat hook creates one Supabase Realtime channel per signed-in session, named chat-{user.id}. The channel listens for INSERT events on the messages table filtered to the current user:
supabase.removeChannel(channel) when the component unmounts or the user changes.
System Prompt and Catalog Context
The/api/chat route constructs a system prompt at runtime that embeds the entire vehicle catalog so the model can answer precise questions about specs, pricing, and availability. Each vehicle is formatted as a colon-separated string containing all key fields:
- Base answers on the catalog context, and may supplement with additional relevant information.
- Never alter prices or specifications from the provided context.
- Treat all prices as USD.
- Politely redirect off-topic questions back to the catalog.
Message Storage Schema
All chat messages — both user and assistant — are stored in themessages table in Supabase:
| Column | Type | Description |
|---|---|---|
id | uuid | Primary key, auto-generated |
user_id | uuid | References the Supabase auth user |
role | text | Either 'user' or 'assistant' |
content | text | The message body (supports Markdown for assistant replies) |
created_at | timestamptz | Auto-set on insert, used for ordering |
ChatAssistant component renders content through react-markdown, so the model can return formatted lists, bold text, or tables when describing vehicle comparisons.
The chat is only available to authenticated users. When
user is null, the ChatAssistant component renders a "Inicia sesión para chatear." (“Please sign in to chat”) message in place of the message list and input field.