diff --git a/docs.json b/docs.json index 92dd1f2a9..6a19e6760 100644 --- a/docs.json +++ b/docs.json @@ -20,7 +20,13 @@ "metatags": { "og:site_name": "LangBot Docs", "twitter:card": "summary_large_image", - "og:image": "https://langbot.app/og-image.png" + "og:image": "https://langbot.app/docs/images/social/docs-v2.png", + "og:image:width": "1200", + "og:image:height": "630", + "og:image:type": "image/png", + "og:image:alt": "LangBot Docs — Build. Connect. Extend.", + "twitter:image": "https://langbot.app/docs/images/social/docs-v2.png", + "twitter:image:alt": "LangBot Docs — Build. Connect. Extend." } }, "navbar": { diff --git a/images/social/docs-v2.png b/images/social/docs-v2.png new file mode 100644 index 000000000..acbe3d670 Binary files /dev/null and b/images/social/docs-v2.png differ diff --git a/package.json b/package.json index cc8c06860..5c9c24b81 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "generate:sitemap-alternates": "node scripts/generate-alternate-sitemap.mjs", "sync:articles": "node scripts/sync-blog-articles.mjs", "check:articles": "node scripts/sync-blog-articles.mjs --check", - "test": "node --test tests/locale-preference.test.mjs tests/agent-docs.test.mjs tests/blog-articles.test.mjs tests/fumapress-migration.test.mjs tests/seo.test.mjs && python3 -m unittest discover -s tests -p 'test_*.py'", + "test": "node --test tests/social-preview.test.mjs tests/locale-preference.test.mjs tests/agent-docs.test.mjs tests/blog-articles.test.mjs tests/fumapress-migration.test.mjs tests/seo.test.mjs && python3 -m unittest discover -s tests -p 'test_*.py'", "finalize:base-path": "node scripts/finalize-base-path.mjs" }, "dependencies": { diff --git a/press.config.tsx b/press.config.tsx index a68713a02..54ede693a 100644 --- a/press.config.tsx +++ b/press.config.tsx @@ -404,6 +404,9 @@ export default defineConfig({ // One registration is intentional: its adapter and loader plugin handle all // OpenAPI virtual pages, regardless of which content source generated them. .plugins( + // Replace the recommended generic Takumi artwork with our shared static + // brand card. Keeping its plugin name suppresses duplicate og:image tags. + { name: "core:takumi" }, { name: "langbot:locale-preference", init() { diff --git a/tests/social-preview.test.mjs b/tests/social-preview.test.mjs new file mode 100644 index 000000000..b9b41a5b7 --- /dev/null +++ b/tests/social-preview.test.mjs @@ -0,0 +1,20 @@ +import assert from "node:assert/strict"; +import { readFileSync, existsSync } from "node:fs"; +import test from "node:test"; +import { fileURLToPath } from "node:url"; +import path from "node:path"; +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); +test("share metadata references the branded versioned preview", () => { + for (const file of ['docs.json']) { + assert.ok(readFileSync(path.join(root, file), "utf8").includes('/images/social/docs-v2.png'), file); + } +}); +test("sharing PNG is a small 1200 by 630 image", () => { + const file = path.join(root, 'images/social/docs-v2.png'); + assert.ok(existsSync(file), "branded image is present"); + const png = readFileSync(file); + assert.equal(png.subarray(1, 4).toString(), "PNG"); + assert.equal(png.readUInt32BE(16), 1200); + assert.equal(png.readUInt32BE(20), 630); + assert.ok(png.length < 200_000); +});