Skip to content

Commit bd4c432

Browse files
committed
fix(docs-og-image): match reference cover template typography exactly
- swap Season Sans for Söhne Kräftig (500) — the reference cover's actual brand font, confirmed by letterform comparison; recovered from git history since it was removed as an unused static asset - fix ink/background colors to exact reference hex values - square caps + miter join on the corner arrow to match the reference's sharp corners instead of rounded ones - recalibrate title font size, line height, and wrap width for the new font's metrics
1 parent 3a2f4e5 commit bd4c432

3 files changed

Lines changed: 27 additions & 30 deletions

File tree

apps/docs/app/api/og/route.tsx

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,25 @@ import type { NextRequest } from 'next/server'
55
export const runtime = 'edge'
66

77
const TITLE_FONT_SIZE = {
8-
large: 105,
9-
medium: 91,
10-
small: 81,
8+
large: 110,
9+
medium: 96,
10+
small: 85,
1111
} as const
1212
/** Average glyph width as a fraction of font size, for this weight/family — used to pack words into lines. */
13-
const AVG_CHAR_WIDTH_EM = 0.46
13+
const AVG_CHAR_WIDTH_EM = 0.42
1414
const TITLE_BOX_WIDTH = 1020
1515
const FONT_CACHE_REVALIDATE_SECONDS = 60 * 60 * 24 * 30
16-
/** Measured off the reference cover template (`apps/sim/public/library/best-zapier-alternatives/cover.jpg`). */
17-
const INK_COLOR = '#525252'
16+
/** Exact hex from a vector trace of the reference cover template, not an estimate off compressed JPEG pixels. */
17+
const INK_COLOR = '#515151'
1818
const OG_CONTAINER_STYLE = {
1919
height: '100%',
2020
width: '100%',
2121
display: 'flex',
2222
flexDirection: 'column',
2323
justifyContent: 'space-between',
2424
padding: '26px',
25-
background: '#c3c3c3',
26-
fontFamily: 'Season',
25+
background: '#c1c1c1',
26+
fontFamily: 'Soehne',
2727
} satisfies CSSProperties
2828
const OG_HEADER_STYLE = {
2929
display: 'flex',
@@ -34,10 +34,12 @@ const OG_HEADER_STYLE = {
3434
const OG_TITLE_STYLE = {
3535
display: 'flex',
3636
flexDirection: 'column',
37-
fontWeight: 600,
37+
fontWeight: 500,
3838
color: INK_COLOR,
39-
lineHeight: 1.15,
39+
lineHeight: 1.1,
4040
width: `${TITLE_BOX_WIDTH}px`,
41+
/** Compensates for Satori adding extra invisible leading below the last line instead of splitting it evenly. */
42+
transform: 'translateY(14px)',
4143
} satisfies CSSProperties
4244

4345
function getTitleFontSize(title: string): number {
@@ -83,21 +85,16 @@ function wrapTitleLines(title: string, fontSize: number): string[] {
8385
}
8486

8587
/**
86-
* Loads a static (600/semibold) TTF instance of the site's own Season Sans
87-
* font — the platform's real brand/body font, also used by the library/blog
88-
* cover template this OG image matches. Instantiated from the variable font
89-
* at `apps/docs/app/fonts/SeasonSansUprightsVF.woff2` (`fonttools
90-
* varLib.instancer wght=600`, then flavor-stripped to plain TTF) rather than
91-
* loading the variable WOFF2 directly: Satori (`next/og`'s renderer) can't
92-
* parse variable fonts without excessive memory use, and can't parse WOFF2
93-
* at all ("Unsupported OpenType signature wOF2") — it needs an uncompressed
94-
* TTF/OTF. Fetched over HTTP since the edge runtime has no filesystem access
95-
* — served from `/static/fonts/` (not `/fonts/`) so it isn't intercepted by
96-
* the site's i18n proxy (`proxy.ts`), whose matcher excludes `static` but
97-
* not `fonts`.
88+
* Loads Söhne Kräftig (weight 500), the typeface used on the reference cover
89+
* template this OG image matches. Converted to a plain TTF from the
90+
* last-shipped `soehne-kraftig.woff2` since Satori (`next/og`'s renderer)
91+
* can't parse WOFF2 or variable fonts. Fetched over HTTP since the edge
92+
* runtime has no filesystem access — served from `/static/fonts/` (not
93+
* `/fonts/`) so it isn't intercepted by the site's i18n proxy (`proxy.ts`),
94+
* whose matcher excludes `static` but not `fonts`.
9895
*/
99-
async function loadSeasonFont(baseUrl: string): Promise<ArrayBuffer> {
100-
const response = await fetch(new URL('/static/fonts/SeasonSans-600-static.ttf', baseUrl), {
96+
async function loadTitleFont(baseUrl: string): Promise<ArrayBuffer> {
97+
const response = await fetch(new URL('/static/fonts/Soehne-Kraftig.ttf', baseUrl), {
10198
next: { revalidate: FONT_CACHE_REVALIDATE_SECONDS },
10299
})
103100

@@ -128,16 +125,16 @@ function SimWordmark() {
128125
)
129126
}
130127

131-
/** Diagonal "open" arrow, top-right — matches the library/blog cover template. */
128+
/** Diagonal "open" arrow, top-right — square caps and a miter join to match the reference's sharp corners. */
132129
function CornerArrow() {
133130
return (
134131
<svg width='58' height='58' viewBox='0 0 24 24' fill='none'>
135132
<path
136133
d='M2 22 22 2M22 2H12M22 2V12'
137134
stroke={INK_COLOR}
138135
strokeWidth={3.6}
139-
strokeLinecap='round'
140-
strokeLinejoin='round'
136+
strokeLinecap='square'
137+
strokeLinejoin='miter'
141138
/>
142139
</svg>
143140
)
@@ -153,7 +150,7 @@ export async function GET(request: NextRequest) {
153150
const { searchParams } = new URL(request.url)
154151
const title = searchParams.get('title') || 'Documentation'
155152

156-
const fontData = await loadSeasonFont(request.url)
153+
const fontData = await loadTitleFont(request.url)
157154
const fontSize = getTitleFontSize(title)
158155
const titleLines = wrapTitleLines(title, fontSize)
159156

@@ -175,10 +172,10 @@ export async function GET(request: NextRequest) {
175172
height: 675,
176173
fonts: [
177174
{
178-
name: 'Season',
175+
name: 'Soehne',
179176
data: fontData,
180177
style: 'normal',
181-
weight: 600,
178+
weight: 500,
182179
},
183180
],
184181
}
-155 KB
Binary file not shown.
94.7 KB
Binary file not shown.

0 commit comments

Comments
 (0)