forked from
danabra.mov/overreacted
my blog https://overreacted.io
1import { ImageResponse } from "next/og";
2import { readFile } from "node:fs/promises";
3import { join } from "node:path";
4
5export const size = {
6 width: 1200,
7 height: 630,
8};
9
10export const contentType = "image/png";
11
12export async function generateHomeImage() {
13 return generateImage(
14 <div
15 style={{
16 display: "flex",
17 width: "100%",
18 height: "100%",
19 backgroundColor: "rgb(40, 44, 53)",
20 color: "white",
21 }}
22 >
23 <div
24 style={{
25 display: "flex",
26 fontSize: 150,
27 width: "100%",
28 height: "100%",
29 flexDirection: "column",
30 justifyContent: "center",
31 alignItems: "center",
32 gap: 80,
33 }}
34 >
35 <span
36 style={{
37 backgroundImage: "linear-gradient(45deg, #ffb3d8, #cbb6ff)",
38 backgroundClip: "text",
39 WebkitBackgroundClip: "text",
40 color: "transparent",
41 }}
42 >
43 overreacted
44 </span>
45 <span
46 style={{
47 fontFamily: "Merriweather",
48 fontStyle: "italic",
49 fontSize: 60,
50 alignItems: "center",
51 }}
52 >
53 by
54 <img
55 alt="Dan Abramov"
56 src="https://github.com/gaearon.png"
57 style={{
58 height: 120,
59 width: 120,
60 borderRadius: "50%",
61 marginLeft: 20,
62 }}
63 />
64 </span>
65 </div>
66 </div>,
67 );
68}
69
70export async function generatePostImage({ title }) {
71 return generateImage(
72 <div
73 style={{
74 padding: 40,
75 display: "flex",
76 flexDirection: "column",
77 width: "100%",
78 height: "100%",
79 backgroundColor: "rgb(40, 44, 53)",
80 color: "white",
81 }}
82 >
83 <div
84 style={{
85 display: "flex",
86 fontSize: 40,
87 width: "100%",
88 justifyContent: "space-between",
89 alignItems: "center",
90 paddingBottom: 20,
91 }}
92 >
93 <span
94 style={{
95 backgroundImage: "linear-gradient(45deg, #ffb3d8, #cbb6ff)",
96 backgroundClip: "text",
97 WebkitBackgroundClip: "text",
98 color: "transparent",
99 fontSize: 60,
100 }}
101 >
102 overreacted
103 </span>
104 <span
105 style={{
106 fontFamily: "Merriweather",
107 fontStyle: "italic",
108 fontSize: 35,
109 alignItems: "center",
110 }}
111 >
112 by
113 <img
114 alt="Dan Abramov"
115 src="https://github.com/gaearon.png"
116 style={{
117 height: 80,
118 width: 80,
119 borderRadius: "50%",
120 marginLeft: 20,
121 }}
122 />
123 </span>
124 </div>
125 <div
126 style={{
127 fontSize: 90,
128 display: "flex",
129 alignItems: "center",
130 flex: 1,
131 paddingBottom: 30,
132 }}
133 >
134 {title}
135 </div>
136 </div>,
137 );
138}
139
140async function generateImage(jsx) {
141 return new ImageResponse(jsx, {
142 ...size,
143 fonts: [
144 {
145 name: "Montserrat",
146 data: await montserratExtraBold,
147 style: "normal",
148 weight: 900,
149 },
150 {
151 name: "Merriweather",
152 data: await merriweatherRegular,
153 style: "normal",
154 weight: 500,
155 },
156 {
157 name: "Merriweather",
158 data: await merriweatherItalic,
159 style: "italic",
160 weight: 500,
161 },
162 ],
163 });
164}
165
166const montserratExtraBold = readFile(
167 join(process.cwd(), "og/Montserrat-ExtraBold.ttf"),
168);
169const merriweatherRegular = readFile(
170 join(process.cwd(), "og/Merriweather-Regular.ttf"),
171);
172const merriweatherItalic = readFile(
173 join(process.cwd(), "og/Merriweather-Italic.ttf"),
174);