layout.tsx 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import type { Metadata } from "next";
  2. import localFont from "next/font/local";
  3. import "./globals.css";
  4. import { ThemeProvider } from "@/components/theme-provider";
  5. import { Analytics } from "@vercel/analytics/next";
  6. import { SpeedInsights } from "@vercel/speed-insights/next";
  7. const geistSans = localFont({
  8. src: "./fonts/GeistVF.woff",
  9. variable: "--font-geist-sans",
  10. });
  11. const geistMono = localFont({
  12. src: "./fonts/GeistMonoVF.woff",
  13. variable: "--font-geist-mono",
  14. });
  15. export const metadata: Metadata = {
  16. metadataBase: new URL("https://json-render.dev"),
  17. title: {
  18. default: "json-render | AI-generated UI with guardrails",
  19. template: "%s | json-render",
  20. },
  21. description:
  22. "Let users generate dashboards, widgets, apps, and data visualizations from prompts — safely constrained to components you define.",
  23. keywords: [
  24. "json-render",
  25. "AI UI generation",
  26. "React components",
  27. "guardrails",
  28. "structured output",
  29. "dashboard builder",
  30. ],
  31. authors: [{ name: "Vercel Labs" }],
  32. creator: "Vercel Labs",
  33. openGraph: {
  34. type: "website",
  35. locale: "en_US",
  36. url: "https://json-render.dev",
  37. siteName: "json-render",
  38. title: "json-render | AI-generated UI with guardrails",
  39. description:
  40. "Let users generate dashboards, widgets, apps, and data visualizations from prompts — safely constrained to components you define.",
  41. images: [
  42. {
  43. url: "/og",
  44. width: 1200,
  45. height: 630,
  46. alt: "json-render - AI-generated UI with guardrails",
  47. },
  48. ],
  49. },
  50. twitter: {
  51. card: "summary_large_image",
  52. title: "json-render | AI-generated UI with guardrails",
  53. description:
  54. "Let users generate dashboards, widgets, apps, and data visualizations from prompts — safely constrained to components you define.",
  55. images: ["/og"],
  56. creator: "@verabornnot",
  57. },
  58. robots: {
  59. index: true,
  60. follow: true,
  61. },
  62. icons: {
  63. icon: "/favicon.ico",
  64. },
  65. };
  66. export default function RootLayout({
  67. children,
  68. }: Readonly<{
  69. children: React.ReactNode;
  70. }>) {
  71. return (
  72. <html lang="en" suppressHydrationWarning>
  73. <body className={`${geistSans.variable} ${geistMono.variable}`}>
  74. <ThemeProvider>{children}</ThemeProvider>
  75. <Analytics />
  76. <SpeedInsights />
  77. </body>
  78. </html>
  79. );
  80. }