authorgravatar for me@t3.ggTheo Browne <me@t3.gg> 2026-09-05 23:28:05-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-05 23:28:05-07:00
logd924fe266483e1d400775e3c3ce784f8e90f355f
tree0f70ea07877a714b9b503aa54a22d4cb1ed0b708
parent272d6d747ef214f50dbd9d0051120de12ffa3591
signature Signed by PGP key B5690EEEBB952194

fix(marketing): show a real preview card when t3.codes is shared (#10305)

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>

2 files changed, 33 insertions(+), 1 deletions(-)

apps/marketing/astro.config.mjs+1
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1import { defineConfig } from "astro/config";1import { defineConfig } from "astro/config";
22
3export default defineConfig({3export default defineConfig({
4 site: "https://t3.codes",
4 server: {5 server: {
5 port: Number(process.env.PORT ?? 4173),6 port: Number(process.env.PORT ?? 4173),
6 },7 },
apps/marketing/src/layouts/Layout.astro+32-1
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1---1---
2import { Image } from "astro:assets";2import { getImage, Image } from "astro:assets";
3import appIcon from "../assets/icon.webp";3import appIcon from "../assets/icon.webp";
4import desktopScreenshot from "../assets/app-desktop.webp";
4import dmSansLatinUrl from "../assets/fonts/dm-sans-latin.woff2?url";5import dmSansLatinUrl from "../assets/fonts/dm-sans-latin.woff2?url";
5import "../styles/fonts.css";6import "../styles/fonts.css";
6import {7import {
...@@ -21,6 +22,21 @@ const {...@@ -21,6 +22,21 @@ const {
21 description = "T3 Code. The open-source control plane for coding agents.",22 description = "T3 Code. The open-source control plane for coding agents.",
22 pageClass,23 pageClass,
23} = Astro.props;24} = Astro.props;
25
26// Social preview card. Link unfurlers (Instagram, iMessage, X, Slack) want a
27// 1200x630 jpg or png at an absolute URL. Built from the hero screenshot so it
28// stays in sync with the homepage.
29const socialImage = await getImage({
30 src: desktopScreenshot,
31 width: 1200,
32 height: 630,
33 fit: "cover",
34 position: "top",
35 format: "jpg",
36 quality: 90,
37});
38const socialImageUrl = new URL(socialImage.src, Astro.site);
39const canonicalUrl = new URL(Astro.url.pathname, Astro.site);
24---40---
2541
26<html lang="en">42<html lang="en">
...@@ -28,6 +44,21 @@ const {...@@ -28,6 +44,21 @@ const {
28 <meta charset="UTF-8" />44 <meta charset="UTF-8" />
29 <meta name="viewport" content="width=device-width, initial-scale=1.0" />45 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
30 <meta name="description" content={description} />46 <meta name="description" content={description} />
47 <link rel="canonical" href={canonicalUrl} />
48 <meta property="og:type" content="website" />
49 <meta property="og:site_name" content="T3 Code" />
50 <meta property="og:url" content={canonicalUrl} />
51 <meta property="og:title" content={title} />
52 <meta property="og:description" content={description} />
53 <meta property="og:image" content={socialImageUrl} />
54 <meta property="og:image:width" content="1200" />
55 <meta property="og:image:height" content="630" />
56 <meta property="og:image:alt" content="The T3 Code desktop app with a thread open." />
57 <meta name="twitter:card" content="summary_large_image" />
58 <meta name="twitter:site" content="@t3dotgg" />
59 <meta name="twitter:title" content={title} />
60 <meta name="twitter:description" content={description} />
61 <meta name="twitter:image" content={socialImageUrl} />
31 <link62 <link
32 rel="preload"63 rel="preload"
33 href={dmSansLatinUrl}64 href={dmSansLatinUrl}