To use LiveChat with V0 by Vercel, embed the LiveChat widget script in your Next.js layout, then create a Next.js API route using your LIVECHAT_ACCOUNT_ID and LIVECHAT_PAT (Personal Access Token) to fetch chat history and agent data. The widget loads automatically on every page and chat data is accessible server-side for custom support dashboards.
Adding LiveChat Widget and API to Your V0 Next.js App
LiveChat is one of the most widely used live support tools for SaaS products and e-commerce sites. Adding the LiveChat chat widget to a V0-generated Next.js app gives visitors instant access to your support team, while the LiveChat REST API lets you build custom dashboards, pull chat transcripts, and monitor agent performance.
The integration has two distinct parts. The first is the widget embed — a small JavaScript snippet that loads the LiveChat chat button on every page. In a Next.js App Router project, this belongs in the root layout.tsx using Next.js's built-in Script component with a 'afterInteractive' strategy so it doesn't block page rendering. The second part is the API integration — using your LiveChat Personal Access Token to call the REST API from a Next.js server-side route. This gives you access to chat history, agent status, visitor data, and analytics.
This tutorial covers both parts: embedding the widget in the layout, creating an API route for chat data, identifying logged-in users to LiveChat (so agents can see who they're talking to), and building a support metrics dashboard. Whether you need just the widget or the full API integration depends on your use case — this guide covers everything so you can pick the parts you need.
Integration method
V0 generates the support dashboard UI and any custom chat-related components. The LiveChat widget is embedded directly in the Next.js root layout as a Script tag that loads on every page. Authenticated API calls to the LiveChat REST API are proxied through a Next.js API route to keep your Personal Access Token server-side.
Prerequisites
- A V0 account at v0.dev — the free tier works for this tutorial
- A LiveChat account at livechat.com — a 14-day free trial is available
- Your LiveChat License ID (also called Account ID) — visible in the LiveChat widget installation code in Settings
- A Personal Access Token (PAT) from LiveChat Developer Console for API access — not required for widget-only integration
- A Vercel account (free) for environment variable storage and deployment
Step-by-step guide
Find Your LiveChat License ID and Create a PAT
Find Your LiveChat License ID and Create a PAT
Start by collecting the two credentials you'll need. Your LiveChat License ID (sometimes called Account ID) identifies your LiveChat account for the widget embed — it's a number like 12345678. Find it by logging into LiveChat at app.livechatinc.com and going to Settings → Chat Widget → Installation. The installation snippet will look like this: window.__lc = window.__lc || {}; window.__lc.license = 12345678. That number is your license ID. For API access, you need a Personal Access Token. Go to the LiveChat Developer Console at developers.livechat.com, sign in with your LiveChat account, go to Tools → Personal Access Tokens, and click Create new token. Give it a name, select the scopes you need — at minimum chats_read and agents_read for a dashboard — and click Create. Copy the token immediately, as it won't be shown again. The PAT is a long string that authenticates your API route requests. Note: if you only need the widget embed (no custom dashboard or API calls), you only need the license ID — you can skip creating a PAT. However, for any feature that reads chat data, the PAT is required.
Pro tip: Create a PAT with the minimum scopes you actually need. If your dashboard only reads chat history, request chats_read only — this follows the principle of least privilege.
Expected result: You have the LiveChat License ID (a number) and optionally a Personal Access Token. Both are saved securely and not pasted into any code file or V0 chat.
Embed the LiveChat Widget in the Root Layout
Embed the LiveChat Widget in the Root Layout
The LiveChat widget needs to load on every page of your app, which makes the root layout the perfect place for it. Open app/layout.tsx in V0's code editor. You'll use Next.js's built-in Script component to load the LiveChat initialization script. The Script component has a strategy prop that controls when the script loads: 'afterInteractive' is the right choice for LiveChat because it loads after the page becomes interactive without blocking rendering. Never use strategy='beforeInteractive' for third-party chat widgets as it delays the main content from appearing. The LiveChat initialization snippet sets the license ID before loading the main script. Import Script from 'next/script' and add it inside the <body> tag in your layout's return statement, just before the closing tag. Pass the license ID as an environment variable using process.env.NEXT_PUBLIC_LIVECHAT_LICENSE_ID — note the NEXT_PUBLIC_ prefix here because this value is used in a client-side script. The license ID is not a secret (it appears in your HTML source for any visitor), so using NEXT_PUBLIC_ is correct and safe. The async src attribute loads the LiveChat script from LiveChat's CDN. After deployment, the chat button will appear in the bottom-right corner of every page in your app within a few seconds of the page loading.
Add the LiveChat widget to the root layout. Import Script from 'next/script'. Add an inline Script tag with strategy='afterInteractive' that initializes window.__lc with the license number from process.env.NEXT_PUBLIC_LIVECHAT_LICENSE_ID and a separate Script tag that loads 'https://cdn.livechatinc.com/tracking.js' asynchronously.
Paste this in V0 chat
1import Script from 'next/script';23export default function RootLayout({ children }: { children: React.ReactNode }) {4 return (5 <html lang="en">6 <body>7 {children}89 {/* LiveChat Widget */}10 <Script id="livechat-init" strategy="afterInteractive">11 {`12 window.__lc = window.__lc || {};13 window.__lc.license = ${process.env.NEXT_PUBLIC_LIVECHAT_LICENSE_ID};14 window.__lc.integration_name = "manual_onboarding";15 window.__lc.product_name = "livechat";16 ;(function(n,t,c){function i(n){return e._h?e._h.apply(null,n):e._q.push(n)}var e={_q:[],_h:null,_v:"2.0",on:function(){i(["on",c.call(arguments)])},once:function(){i(["once",c.call(arguments)])},off:function(){i(["off",c.call(arguments)])},get:function(){if(!e._h)throw new Error("[LiveChatWidget] You can't use getters before load.");return i(["get",c.call(arguments)])},call:function(){i(["call",c.call(arguments)])},init:function(){var n=t.createElement("script");n.async=!0,n.type="text/javascript",n.src="https://cdn.livechatinc.com/tracking.js",t.head.appendChild(n)}};!n.__lc.asyncInit&&e.init(),n.LiveChatWidget=n.LiveChatWidget||e}(window,document,[].slice))17 `}18 </Script>19 </body>20 </html>21 );22}Pro tip: The LiveChat widget respects the user's chat window state (open/minimized) across page navigations in a Next.js SPA — users don't lose their chat when they navigate between pages.
Expected result: After deploying, the LiveChat chat button appears in the bottom-right corner of every page. Opening it shows the pre-chat form or an active chat with your support agents.
Create the LiveChat API Route for Dashboard Data
Create the LiveChat API Route for Dashboard Data
To build a custom support dashboard that shows chat history, agent status, or analytics, you need to call LiveChat's REST API from a server-side API route. Create app/api/livechat/route.ts. The LiveChat REST API v3 base URL is https://api.livechatinc.com/v3.5. Authentication uses HTTP Basic Auth with your account email as the username and your Personal Access Token as the password. The most useful endpoints for a dashboard are: GET /chats to list recent chat sessions, GET /agents to list all agents and their current status, and GET /reports/chats to get aggregated metrics. The fetch call encodes the credentials as a Base64 Basic Auth header. Use btoa in Node.js to encode the credentials — the pattern is btoa('email:pat'). The response includes pagination via the next_page_id cursor — add support for pagination if you need to display more than 20 chats. For the dashboard, start with the /reports/chats endpoint to get aggregated daily statistics (total chats, average response time, customer satisfaction score) and the /chats endpoint for the recent chat list. Return only the fields the frontend needs to minimize payload size. The 'afterInteractive' Script strategy means the widget itself never calls this API route — the API route is only for your admin dashboard components.
Create a support dashboard page that fetches data from GET /api/livechat/stats and GET /api/livechat/chats. Show three metric cards at the top and a sortable table of recent chats below. Add a loading skeleton while fetching.
Paste this in V0 chat
1import { NextRequest } from 'next/server';23const LIVECHAT_EMAIL = process.env.LIVECHAT_EMAIL!;4const LIVECHAT_PAT = process.env.LIVECHAT_PAT!;5const BASE_URL = 'https://api.livechatinc.com/v3.5';67function getAuthHeader() {8 const credentials = Buffer.from(`${LIVECHAT_EMAIL}:${LIVECHAT_PAT}`).toString('base64');9 return `Basic ${credentials}`;10}1112export async function GET(request: NextRequest) {13 const { searchParams } = new URL(request.url);14 const type = searchParams.get('type') ?? 'chats';1516 const headers = {17 Authorization: getAuthHeader(),18 'Content-Type': 'application/json',19 };2021 if (type === 'agents') {22 const res = await fetch(`${BASE_URL}/agents?fields=id,name,email,present,chat_count`, {23 headers,24 });25 const data = await res.json();26 return Response.json(data);27 }2829 if (type === 'stats') {30 const today = new Date().toISOString().split('T')[0];31 const res = await fetch(32 `${BASE_URL}/reports/chats?distribution=day&from=${today}&to=${today}`,33 { headers }34 );35 const data = await res.json();36 return Response.json(data);37 }3839 // Default: recent chats40 const res = await fetch(`${BASE_URL}/chats?limit=20&sort_order=desc`, { headers });41 const data = await res.json();42 return Response.json(data);43}Pro tip: The LiveChat API uses cursor-based pagination with next_page_id. If you need more than 20 results, pass the returned next_page_id as a query parameter in the next request.
Add Credentials to Vercel and Configure User Identification
Add Credentials to Vercel and Configure User Identification
Add your LiveChat credentials to Vercel's environment variables. Open Vercel Dashboard → your project → Settings → Environment Variables. Add NEXT_PUBLIC_LIVECHAT_LICENSE_ID with the NEXT_PUBLIC_ prefix (it's safe — this value is public and appears in your HTML source). Add LIVECHAT_EMAIL as your LiveChat account email (server-only, no NEXT_PUBLIC_ prefix). Add LIVECHAT_PAT as your Personal Access Token (server-only, never prefix with NEXT_PUBLIC_). Check all three environment scopes for each variable. After saving, redeploy. For local development, add all three to .env.local. An important enhancement for SaaS apps is user identification: after the widget loads, you can pass the logged-in user's details to LiveChat so agents see the customer's name and email without asking. In a client component that has access to the current user, add a useEffect that runs after the LiveChat widget loads, using the LiveChatWidget.call() API. This dramatically improves support quality. The identification call should only run when you have confirmed user data — wrap it in a check for user existence. For security, LiveChat Enterprise supports identity verification using HMAC signatures — this prevents customers from impersonating other users by passing someone else's email.
Create a ChatIdentifier client component that accepts a user prop with { name, email, plan } fields. In a useEffect, call window.LiveChatWidget.call('set_customer_name', user.name), window.LiveChatWidget.call('set_customer_email', user.email), and window.LiveChatWidget.call('set_session_variables', { plan: user.plan }) when the user prop is truthy. Add this component to the authenticated app layout.
Paste this in V0 chat
1'use client';23import { useEffect } from 'react';45interface ChatIdentifierProps {6 user: {7 name: string;8 email: string;9 plan?: string;10 } | null;11}1213export function ChatIdentifier({ user }: ChatIdentifierProps) {14 useEffect(() => {15 if (!user || typeof window === 'undefined') return;1617 // LiveChatWidget may not be ready yet — wait for it18 const identify = () => {19 if (!window.LiveChatWidget) return;20 window.LiveChatWidget.call('set_customer_name', user.name);21 window.LiveChatWidget.call('set_customer_email', user.email);22 if (user.plan) {23 window.LiveChatWidget.call('set_session_variables', { plan: user.plan });24 }25 };2627 if (window.LiveChatWidget) {28 identify();29 } else {30 window.addEventListener('LiveChatWidget:ready', identify, { once: true });31 }3233 return () => window.removeEventListener('LiveChatWidget:ready', identify);34 }, [user]);3536 return null; // No visible UI — this component only runs side effects37}Pro tip: The ChatIdentifier component returns null — it has no visible UI. Place it in your authenticated layout near the user data source so it receives fresh user data on every session.
Expected result: The LiveChat widget appears on all pages. Logged-in users' names and emails appear automatically in the LiveChat agent dashboard when they start a chat. The API route returns agent and chat data for the dashboard.
Common use cases
Live Support Widget on Marketing Site
Add the LiveChat widget to every page of a V0-generated marketing site or SaaS landing page. Visitors can start a chat from any page, and your support team sees the page they're on. This is the simplest use case — just the widget embed with no API calls required.
Add a floating chat button in the bottom-right corner of the page that opens a LiveChat widget. The button should show a chat icon and the text 'Chat with us' on desktop and just the icon on mobile. The LiveChat script will load automatically — this component is just the visual indicator before the script loads.
Copy this prompt to try it in V0
Support Dashboard with Chat History
Build an internal support dashboard for your team that shows recent chats, average response times, and customer satisfaction scores fetched from the LiveChat API. Agents get a custom view of their performance metrics without switching to LiveChat's default interface.
Create a support dashboard page with three metric cards at the top showing: total chats today, average response time, and satisfaction score with trend arrows. Below the cards, show a table of recent chats with columns for customer name, start time, duration, agent name, and a satisfaction rating with star icons. Add a date range filter at the top. The component should accept a stats prop and a chats prop array.
Copy this prompt to try it in V0
Identified Chat for Logged-In Users
For SaaS apps with user authentication, pass the logged-in user's name, email, and plan to LiveChat so support agents can immediately see who they're helping without asking for contact details. This dramatically improves support quality and response speed.
Add a LiveChat widget to the authenticated app layout that pre-fills the chat with the current user's name and email. Create a ChatIdentifier client component that reads user data from a context or prop and sets LiveChat customer attributes. The component should call window.LiveChatWidget.call('set_customer_name', user.name) and set_customer_email after the widget loads.
Copy this prompt to try it in V0
Troubleshooting
LiveChat widget doesn't appear on the page after deploying
Cause: The NEXT_PUBLIC_LIVECHAT_LICENSE_ID environment variable is missing in Vercel, or the Script component is placed outside the <body> tag in layout.tsx.
Solution: Verify NEXT_PUBLIC_LIVECHAT_LICENSE_ID is set in Vercel Dashboard → Settings → Environment Variables and that it's available for the Production environment. Redeploy after adding it. Also confirm the Script tag is inside the <body> element in app/layout.tsx — placing it in <head> can cause loading issues.
API route returns 401 Unauthorized when fetching chat data
Cause: The Basic Auth header is incorrectly encoded, the LIVECHAT_EMAIL or LIVECHAT_PAT is wrong, or the PAT was created without the required scopes.
Solution: Verify LIVECHAT_EMAIL matches the email address of your LiveChat account (not just any team member). Confirm LIVECHAT_PAT is the Personal Access Token created in the Developer Console, not an API key or webhook token. Regenerate the PAT if unsure, and verify it has at minimum chats_read scope.
1// Verify the Basic Auth encoding2const credentials = Buffer.from(`${process.env.LIVECHAT_EMAIL}:${process.env.LIVECHAT_PAT}`).toString('base64');3console.log('Auth header:', `Basic ${credentials.substring(0, 10)}...`); // Log partial value to verify formatwindow.LiveChatWidget is undefined when ChatIdentifier tries to call it
Cause: The LiveChat script hasn't finished loading when the ChatIdentifier's useEffect runs. This is a race condition — the Script with strategy='afterInteractive' loads asynchronously.
Solution: Use the LiveChatWidget:ready event listener as shown in the ChatIdentifier code in Step 4. The component should listen for this event when window.LiveChatWidget is not yet defined, and call the identification methods in the event handler.
1// Wait for the widget to be ready before calling its methods2if (window.LiveChatWidget) {3 identify();4} else {5 window.addEventListener('LiveChatWidget:ready', identify, { once: true });6}Best practices
- Load the LiveChat script with strategy='afterInteractive' in the Next.js Script component — this prevents the widget from blocking page rendering
- Keep LIVECHAT_PAT server-side without NEXT_PUBLIC_ prefix — the PAT should only be used in API routes, never in client components
- Use NEXT_PUBLIC_LIVECHAT_LICENSE_ID for the widget license ID — it's a public value that appears in your page HTML anyway
- Implement user identification in your authenticated layout to give support agents immediate context about who they're helping
- For enterprise accounts, enable identity verification using HMAC signatures to prevent customers from impersonating others in chat
- Use the LiveChat Webhooks API to push chat events (new chat, chat closed, message received) to your own API route for real-time notifications without polling
- Cache LiveChat API responses for dashboard data using Next.js ISR — chat history doesn't change in real time, so a 5-minute cache is reasonable
Alternatives
Intercom is a better choice if you need customer messaging beyond live chat — including automated message sequences, product tours, and a full customer data platform.
Zendesk is the stronger option if your team handles high volumes of support tickets across email, chat, and phone with a unified ticketing workflow.
Freshdesk offers live chat alongside a comprehensive helpdesk and is a better fit if you need to unify support channels at a lower price point than Intercom.
Frequently asked questions
Does V0 have built-in LiveChat support?
V0 does not have a native LiveChat integration or Marketplace connector. You embed the widget manually using the Next.js Script component and call the REST API from your own API route. V0 is excellent for generating the custom support dashboard UI components, while you handle the LiveChat wiring yourself using this tutorial.
Does the LiveChat widget work with Next.js App Router?
Yes. Use the Script component from 'next/script' with strategy='afterInteractive' in your root app/layout.tsx. This approach is compatible with Next.js App Router and ensures the widget loads correctly without blocking rendering. The widget also persists across client-side navigations without reloading.
How do I show the chat widget only on specific pages?
Move the LiveChat Script tag from the root layout to a specific page's layout file or the page component itself. Alternatively, keep it in the root layout and use the LiveChatWidget.call('hide') and LiveChatWidget.call('show') JavaScript API to programmatically control visibility based on the current route using the Next.js usePathname hook in a client component.
Why does my LiveChat widget not appear in V0's browser preview?
V0's browser preview sandbox blocks external scripts for security reasons. The LiveChat widget will not load in the preview. This is expected behavior — the widget works correctly after you deploy to Vercel. You can see the NEXT_PUBLIC_ environment variable is set correctly by checking if the license ID appears in the page source after deployment.
What is the difference between the LiveChat widget and the LiveChat API?
The widget is the chat button and conversation UI that visitors see on your website — embedded via a script tag. The LiveChat REST API is a separate interface for reading and managing data: chat history, agent lists, performance reports. You need the API only if you're building custom dashboards or integrations. The widget works independently and requires only your License ID.
Can I customize the appearance of the LiveChat widget?
Yes, within limits. The primary customization is done through LiveChat's Settings → Chat Widget section in the LiveChat admin panel — you can change colors, greeting messages, agent photos, and the widget position. For code-level customization, use the window.__lc configuration object before the script loads to set properties like greetings and event handlers. Full CSS customization of the widget internals is not supported.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation