-
Notifications
You must be signed in to change notification settings - Fork 1
/
image.tsx
103 lines (96 loc) · 2.63 KB
/
image.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import { ImageResponse } from "next/og";
import { type Font, findLargestUsableFontSize } from "@altano/satori-fit-text";
import nullthrows from "nullthrows";
type ImageResponseOptions = ConstructorParameters<typeof ImageResponse>[1];
type Props = {
cardProps: OpenGraphCardProps;
imageOptions: ImageResponseOptions;
};
type OpenGraphCardProps = {
title: string;
subtitle?: string;
fonts: Font[];
};
export default async function OpenGraphImage(props: Props) {
const { cardProps, imageOptions } = props;
const { fonts, title, subtitle } = cardProps;
const opengraphDimensions = {
width: 1200,
height: 630,
};
const footerHeight = 137;
const padding = 32;
const lineHeight = 1;
const titleFontWeight = 700; /* Bold */
const titleFontSize = await findLargestUsableFontSize({
text: title,
font: nullthrows(fonts.find((f) => f.weight === titleFontWeight)),
maxWidth: opengraphDimensions.width - padding - padding,
maxHeight: opengraphDimensions.height - padding - padding - footerHeight,
lineHeight,
});
const subtitleFontWeight = 600; /* SemiBold */
const subtitleFontSize =
subtitle == null
? 0
: await findLargestUsableFontSize({
text: subtitle,
font: nullthrows(fonts.find((f) => f.weight === subtitleFontWeight)),
maxWidth: opengraphDimensions.width - padding - padding,
maxHeight: footerHeight - padding - padding,
lineHeight,
});
const card = (
<main
style={{
lineHeight,
background: "white",
color: "black",
width: "100vw",
height: "100vh",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
justifyContent: "flex-start",
margin: 0,
boxSizing: "border-box",
}}
>
<h1
style={{
lineHeight,
flexGrow: 1,
width: "100%",
padding,
boxSizing: "border-box",
margin: 0,
fontSize: titleFontSize,
fontWeight: titleFontWeight,
}}
>
{title}
</h1>
{subtitle && (
<footer
style={{
lineHeight,
display: "flex",
alignItems: "center",
background: "#FCDED9",
width: "100%",
flexShrink: 0,
padding,
boxSizing: "border-box",
margin: 0,
height: footerHeight,
fontSize: subtitleFontSize,
fontWeight: subtitleFontWeight,
}}
>
{subtitle}
</footer>
)}
</main>
);
return new ImageResponse(card, imageOptions);
}