From 7b6c3ceb9dd97249e9dce4a8a94e61aed6424698 Mon Sep 17 00:00:00 2001 From: Aurora Scharff <66901228+aurorascharff@users.noreply.github.com> Date: Mon, 20 Jul 2026 15:31:48 +0200 Subject: [PATCH 1/2] [og images] Resize long og image text (#8543) * Resize long og image text * address feedback --- package.json | 1 + scripts/generateOgImages.mjs | 30 +++++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 97bc1432..567102e0 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "@babel/preset-react": "^7.18.6", "@mdx-js/mdx": "^2.1.3", "@resvg/resvg-js": "^2.6.2", + "@shuding/opentype.js": "1.4.0-beta.0", "@types/body-scroll-lock": "^2.6.1", "@types/classnames": "^2.2.10", "@types/debounce": "^1.2.1", diff --git a/scripts/generateOgImages.mjs b/scripts/generateOgImages.mjs index 937727a1..bc805d38 100644 --- a/scripts/generateOgImages.mjs +++ b/scripts/generateOgImages.mjs @@ -14,6 +14,7 @@ import path from 'path'; import satori from 'satori'; import {Resvg} from '@resvg/resvg-js'; import matter from 'gray-matter'; +import opentype from '@shuding/opentype.js'; const ROOT = process.cwd(); const CONTENT_DIR = path.join(ROOT, 'src', 'content'); @@ -34,6 +35,33 @@ const medium = fs.readFileSync( path.join(ROOT, 'public', 'fonts', 'Optimistic_Display_W_Md.ttf') ); +// Title area width: card width minus the horizontal padding (80px per side). +const TITLE_MAX_WIDTH = 1200 - 80 * 2; +const TITLE_MAX_FONT = 96; +const TITLE_MIN_FONT = 56; +// Small margin so borderline titles don't wrap and orphan a single trailing +// character (e.g. the "p" in "renderToStaticMarkup", which is 1px too wide +// to fit on one line at 96px). +const TITLE_SAFETY = 8; + +const boldFont = opentype.parse( + bold.buffer.slice(bold.byteOffset, bold.byteOffset + bold.byteLength) +); + +// Multi-word titles wrap cleanly at spaces, so a length bucket is fine for +// them. Single-word titles (most API names) can only break mid-word, which +// leaves an orphaned letter on its own line, so instead shrink them just +// enough to fit on a single line. +function titleFontSize(title) { + const trimmed = title.trim(); + if (/\s/.test(trimmed)) { + return trimmed.length > 24 ? 72 : 96; + } + const widthPerPx = boldFont.getAdvanceWidth(trimmed, 1); + const fit = Math.floor((TITLE_MAX_WIDTH - TITLE_SAFETY) / widthPerPx); + return Math.max(TITLE_MIN_FONT, Math.min(TITLE_MAX_FONT, fit)); +} + function el(type, style, children) { return {type, props: {style, children}}; } @@ -103,7 +131,7 @@ function card(title, pagePath) { flexGrow: 1, display: 'flex', alignItems: 'center', - fontSize: title.length > 24 ? 72 : 96, + fontSize: titleFontSize(title), fontFamily: 'Optimistic Display Bold', color: '#f6f7f9', lineHeight: 1.1, From 1be9515f7b2759af0ca2f9656ea1c09b01e70d68 Mon Sep 17 00:00:00 2001 From: "Kristijan \"Fremen\" Velkovski" Date: Fri, 21 Aug 2026 10:39:31 -0500 Subject: [PATCH 2/2] Fix merge conflict markers in yarn.lock --- yarn.lock | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3650d44e..a6c0bf40 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2693,21 +2693,12 @@ camelcase-css@^2.0.1: resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz" integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== -<<<<<<< HEAD -caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001286, caniuse-lite@^1.0.30001297, caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001688: -======= camelize@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3" integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== -caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001286, caniuse-lite@^1.0.30001297, caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001579: - version "1.0.30001636" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz#b15f52d2bdb95fad32c2f53c0b68032b85188a78" - integrity sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg== - -caniuse-lite@^1.0.30001688: ->>>>>>> 7b6c3ceb9dd97249e9dce4a8a94e61aed6424698 +caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001286, caniuse-lite@^1.0.30001297, caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001688: version "1.0.30001692" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz#4585729d95e6b95be5b439da6ab55250cd125bf9" integrity sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A== @@ -2866,11 +2857,7 @@ color-name@1.1.3: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -<<<<<<< HEAD -color-name@~1.1.4: -======= color-name@^1.0.0, color-name@^1.1.4, color-name@~1.1.4: ->>>>>>> 7b6c3ceb9dd97249e9dce4a8a94e61aed6424698 version "1.1.4" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==