From 2e771ead53affecd7fe038c3245f473648c10438 Mon Sep 17 00:00:00 2001 From: Mao Nakamoto <41178744+maonakamoto@users.noreply.github.com> Date: Fri, 7 Aug 2026 10:53:57 +0200 Subject: [PATCH] feat(meta): give the site a real social preview MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This site shipped no og:image, so every link to it — Telegram, Slack, a DM — rendered as a blank grey rectangle. Adds the Next file-convention card (1200x630, the size those scrapers crop to) drawn in the site's own palette. Also sets metadataBase, which is load-bearing rather than cosmetic: without it Next resolves the generated image to http://localhost:3000/opengraph-image — a tag that is present, looks configured, and is unfetchable by every scraper. The fallback is the real host, so a missing env var degrades to correct rather than to localhost. Pattern verified end-to-end on a sibling repo: build, render, 200 image/png at 1200x630, and og:image emitted as the absolute production URL. --- frontend/src/app/layout.tsx | 16 +++++++ frontend/src/app/opengraph-image.tsx | 70 ++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 frontend/src/app/opengraph-image.tsx diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index 290aa7fd..d8d81c3e 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -11,9 +11,25 @@ import { UsageMonitor } from './components/UsageMonitor'; const geistSans = GeistSans; const geistMono = GeistMono; +/** + * Where this site actually serves. Load-bearing for the social preview: Next + * resolves the generated og:image against `metadataBase`, and without it the + * tag is emitted as http://localhost:3000/opengraph-image — present, plausible, + * and unfetchable by every scraper. Falls back to the real host, not localhost. + */ +const SITE_URL = process.env.NEXT_PUBLIC_APP_URL || "https://datacat.orangecat.ch"; + export const metadata: Metadata = { + metadataBase: new URL(SITE_URL), title: "Form Builder | KI-gestützter DataCat-Editor", description: "Erstellen Sie schöne, intelligente DataCate für jede Branche – nicht nur HR.", + openGraph: { + title: "DataCat — KI-gestützter Formular-Editor", + description: "Erstellen Sie schöne, intelligente Formulare für jede Branche – nicht nur HR.", + url: SITE_URL, + siteName: "DataCat", + type: "website", + }, }; export default function RootLayout({ diff --git a/frontend/src/app/opengraph-image.tsx b/frontend/src/app/opengraph-image.tsx new file mode 100644 index 00000000..dd07a1f8 --- /dev/null +++ b/frontend/src/app/opengraph-image.tsx @@ -0,0 +1,70 @@ +import { ImageResponse } from "next/og"; + +/** + * Social preview card (1200x630 — the 1.91:1 size Slack, Telegram and the + * OpenGraph scrapers crop to). DataCat shipped no og:image, so every shared + * link rendered as a blank grey rectangle. + * + * Satori cannot read CSS custom properties or Tailwind classes, so the accent + * is repeated here as a literal. It mirrors the indigo-600 used across the app. + */ + +export const runtime = "edge"; +export const alt = "DataCat — KI-gestützter Formular-Editor"; +export const size = { width: 1200, height: 630 }; +export const contentType = "image/png"; + +const INK = "#171717"; +const INDIGO = "#4F46E5"; +const MUTED = "#6B7280"; +const PAPER = "#FFFFFF"; + +export default function OGImage() { + return new ImageResponse( + ( +
+
+
+
+ DataCat +
+
+ +
+
+ Formulare, die mitdenken +
+
+ Erstellen Sie schöne, intelligente Formulare für jede Branche — nicht nur HR. +
+
+ +
+
+
datacat.orangecat.ch
+
+
+ ), + { ...size }, + ); +}