import "@/styles/globals.css"; import type { ReactNode } from "react"; import { GeistSans } from "geist/font/sans"; import { GeistMono } from "geist/font/mono"; import Script from "next/script"; import { Analytics } from "@vercel/analytics/next"; import { Provider } from "./provider"; import { cn } from "@/lib/utils"; import { BASE_URL } from "@/lib/constants"; const getMetadataBase = () => { const appUrl = process.env.NEXT_PUBLIC_APP_URL; if (appUrl) { return new URL(appUrl); } if (process.env.NODE_ENV === "production") { return new URL(BASE_URL); } return new URL("http://localhost:3000"); }; export const viewport = { width: "device-width", initialScale: 1, maximumScale: 1, }; export const metadata = { metadataBase: getMetadataBase(), title: { template: "%s — assistant-ui", default: "assistant-ui - React Chat UI for AI Apps", }, description: "Open-source React components and runtimes for building AI chat — ChatGPT-style UIs, copilots, and agents in TypeScript with streaming, tools, and persistence.", openGraph: { title: "assistant-ui", description: "Open-source React components and runtimes for building AI chat — ChatGPT-style UIs, copilots, and agents in TypeScript with streaming, tools, and persistence.", siteName: "assistant-ui", type: "website", images: [ { url: "/api/og?variant=home", width: 1200, height: 630, alt: "assistant-ui", }, ], }, twitter: { card: "summary_large_image", title: "assistant-ui", description: "Open-source React components and runtimes for building AI chat — ChatGPT-style UIs, copilots, and agents in TypeScript with streaming, tools, and persistence.", images: ["/api/og?variant=home"], }, }; export default function Layout({ children }: { children: ReactNode }) { return ( {/*