my blog https://overreacted.io
at fix/a-socialfilesystem-typos 174 lines 3.9 kB view raw
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);