layout.tsx 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import type { Metadata } from "next";
  2. import { Geist, Geist_Mono } from "next/font/google";
  3. import "./globals.css";
  4. import MatomoTracker from "@/components/MatomoTracker";
  5. import { Toaster } from "@/components/ui/toaster";
  6. import { getSiteUrl } from "@/lib/site";
  7. const geistSans = Geist({
  8. variable: "--font-geist-sans",
  9. subsets: ["latin"],
  10. });
  11. const geistMono = Geist_Mono({
  12. variable: "--font-geist-mono",
  13. subsets: ["latin"],
  14. });
  15. export const metadata: Metadata = {
  16. title: "AI-CS 智能客服系统",
  17. description: "融合 AI 技术与人工客服,为企业提供高效、智能的客户服务解决方案",
  18. };
  19. // Matomo 容器 URL(格式:container_*.js)
  20. const MATOMO_CONTAINER_URL = process.env.NEXT_PUBLIC_MATOMO_CONTAINER_URL || '';
  21. // 后端端口配置(用于 widget.js)
  22. const BACKEND_PORT = process.env.NEXT_PUBLIC_BACKEND_PORT || '18080';
  23. export default function RootLayout({
  24. children,
  25. }: Readonly<{
  26. children: React.ReactNode;
  27. }>) {
  28. return (
  29. <html lang="zh-CN">
  30. <head>
  31. <script
  32. dangerouslySetInnerHTML={{
  33. __html: `window.AICS_BACKEND_PORT = '${BACKEND_PORT}';`,
  34. }}
  35. />
  36. </head>
  37. <body
  38. className={`${geistSans.variable} ${geistMono.variable} antialiased`}
  39. >
  40. {children}
  41. <Toaster />
  42. {MATOMO_CONTAINER_URL && <MatomoTracker containerUrl={MATOMO_CONTAINER_URL} />}
  43. </body>
  44. </html>
  45. );
  46. }