Chris Tate 5 meses atrás
pai
commit
f41833f607
2 arquivos alterados com 94 adições e 2 exclusões
  1. 48 2
      apps/web/app/layout.tsx
  2. 46 0
      apps/web/app/og/route.tsx

+ 48 - 2
apps/web/app/layout.tsx

@@ -17,9 +17,55 @@ const geistMono = localFont({
 });
 
 export const metadata: Metadata = {
-  title: "json-render | AI-powered UI from JSON with guardrails",
+  metadataBase: new URL("https://json-render.dev"),
+  title: {
+    default: "json-render | AI-generated UI with guardrails",
+    template: "%s | json-render",
+  },
   description:
-    "Define a catalog. AI generates JSON. Your components render natively. Enterprise-grade guardrails for controlled AI UI generation.",
+    "Let users generate dashboards, widgets, apps, and data visualizations from prompts — safely constrained to components you define.",
+  keywords: [
+    "json-render",
+    "AI UI generation",
+    "React components",
+    "guardrails",
+    "structured output",
+    "dashboard builder",
+  ],
+  authors: [{ name: "Vercel Labs" }],
+  creator: "Vercel Labs",
+  openGraph: {
+    type: "website",
+    locale: "en_US",
+    url: "https://json-render.dev",
+    siteName: "json-render",
+    title: "json-render | AI-generated UI with guardrails",
+    description:
+      "Let users generate dashboards, widgets, apps, and data visualizations from prompts — safely constrained to components you define.",
+    images: [
+      {
+        url: "/og",
+        width: 1200,
+        height: 630,
+        alt: "json-render - AI-generated UI with guardrails",
+      },
+    ],
+  },
+  twitter: {
+    card: "summary_large_image",
+    title: "json-render | AI-generated UI with guardrails",
+    description:
+      "Let users generate dashboards, widgets, apps, and data visualizations from prompts — safely constrained to components you define.",
+    images: ["/og"],
+    creator: "@verabornnot",
+  },
+  robots: {
+    index: true,
+    follow: true,
+  },
+  icons: {
+    icon: "/favicon.ico",
+  },
 };
 
 export default function RootLayout({

+ 46 - 0
apps/web/app/og/route.tsx

@@ -0,0 +1,46 @@
+import { ImageResponse } from "next/og";
+
+export const runtime = "edge";
+
+export async function GET() {
+  const geistSemiBold = await fetch(
+    new URL("../fonts/GeistVF.woff", import.meta.url),
+  ).then((res) => res.arrayBuffer());
+
+  return new ImageResponse(
+    <div
+      style={{
+        width: "100%",
+        height: "100%",
+        display: "flex",
+        alignItems: "center",
+        justifyContent: "center",
+        backgroundColor: "black",
+      }}
+    >
+      <span
+        style={{
+          fontSize: 72,
+          fontFamily: "Geist",
+          fontWeight: 600,
+          color: "white",
+          letterSpacing: "-0.02em",
+        }}
+      >
+        json-render
+      </span>
+    </div>,
+    {
+      width: 1200,
+      height: 630,
+      fonts: [
+        {
+          name: "Geist",
+          data: geistSemiBold,
+          style: "normal",
+          weight: 600,
+        },
+      ],
+    },
+  );
+}