redirecter for ao3 that adds opengraph metadata
1import { ImageResponse } from "next/og" 2 3export default async function OGImage ({ theme, baseFont, titleFont, image, addr, opts }) { 4 return new ImageResponse( 5 ( 6 <div 7 style={{ 8 display: "flex", 9 flexDirection: "column", 10 color: theme.color, 11 backgroundColor: theme.background, 12 fontFamily: baseFont, 13 fontSize: 24, 14 padding: 20, 15 width: "100%", 16 height: "100%", 17 }} 18 > 19 <div 20 style={{ 21 display: "flex", 22 flexDirection: "column", 23 marginBottom: 20 24 }} 25 > 26 <div 27 style={{ 28 textTransform: "uppercase", 29 display: "flex", 30 justifyContent: "center", 31 gap: 10, 32 color: theme.accent, 33 alignItems: "stretch" 34 }} 35 > 36 <div 37 style={{ 38 display: "flex" 39 }} 40 > 41 {image.topLine} 42 </div> 43 {image.rating && (<div 44 style={{ 45 borderRadius: '100%', 46 backgroundColor: theme.accent, 47 color: theme.background, 48 padding: "0 10px", 49 display: "flex", 50 minWidth: 28, 51 justifyContent: "center", 52 alignItems: "center", 53 fontWeight: "bold" 54 }} 55 > 56 {image.rating} 57 </div>)} 58 {image.warnings && ( 59 <div 60 style={{ 61 borderRadius: '100%', 62 backgroundColor: theme.accent2, 63 color: theme.background, 64 padding: "0 5px", 65 display: "flex", 66 minWidth: 28, 67 justifyContent: "center", 68 alignItems: "center", 69 fontWeight: "bold" 70 }} 71 > 72 {image.warning} 73 </div> 74 )} 75 {image.category && ( 76 <div 77 style={{ 78 borderRadius: '100%', 79 backgroundColor: theme.accent3, 80 color: theme.background, 81 padding: "0 10px", 82 display: "flex", 83 minWidth: 28, 84 justifyContent: "center", 85 alignItems: "center", 86 fontWeight: "bold" 87 }} 88 > 89 {image.category} 90 </div> 91 )} 92 </div> 93 <div 94 style={{ 95 fontSize: 54, 96 justifyContent: "center", 97 fontFamily: titleFont, 98 fontWeight: "bold", 99 color: theme.color 100 }} 101 > 102 {image.titleLine} 103 </div> 104 <div 105 style={{ 106 fontSize: 42, 107 display: "flex", 108 justifyContent: "center", 109 fontFamily: titleFont, 110 color: theme.color 111 }} 112 > 113 {`by ${image.authorLine}`} 114 </div> 115 <div 116 style={{ 117 fontStyle: "italic", 118 fontSize: 36, 119 fontFamily: titleFont, 120 display: "flex", 121 justifyContent: "center", 122 color: theme.color 123 }} 124 > 125 {image.chapterLine} 126 </div> 127 </div> 128 <div 129 style={{ 130 backgroundColor: theme.descBackground, 131 padding: 20, 132 display: "flex", 133 flexDirection: "column", 134 flexGrow: 1, 135 color: theme.descColor, 136 alignItems: "flex-end" 137 }} 138 > 139 {image.props.get("charTags") === 'true' && (<div 140 style={{ 141 display: "flex", 142 flexWrap: "wrap", 143 gap: 5, 144 fontSize: 18, 145 width: "100%", 146 marginBottom: 5 147 }} 148 > 149 {image.charTags.map(c => ( 150 <span 151 style={{ 152 backgroundColor: theme.accent2, 153 color: theme.descBackground, 154 padding: "3px 5px", 155 borderRadius: 5 156 }} 157 > 158 {c} 159 </span> 160 ))} 161 </div>)} 162 {image.props.get("relTags") === 'true' && (<div 163 style={{ 164 display: "flex", 165 flexWrap: "wrap", 166 gap: 5, 167 fontSize: 18, 168 width: "100%", 169 marginBottom: 5 170 }} 171 > 172 {image.relTags.map(r => ( 173 <span 174 style={{ 175 backgroundColor: theme.accent3, 176 color: theme.descBackground, 177 padding: "3px 5px", 178 borderRadius: 5 179 }} 180 > 181 {r} 182 </span> 183 ))} 184 </div>)} 185 {image.props.get("freeTags") === 'true' && (<div 186 style={{ 187 display: "flex", 188 flexWrap: "wrap", 189 gap: 5, 190 fontSize: 18, 191 width: "100%", 192 marginBottom: 5 193 }} 194 > 195 {image.freeTags.map(f => ( 196 <span 197 style={{ 198 backgroundColor: theme.accent4, 199 color: theme.descBackground, 200 padding: "3px 5px", 201 borderRadius: 5 202 }} 203 > 204 {f} 205 </span> 206 ))} 207 </div>)} 208 {image.props.get("summary") === 'true' && (<div 209 style={{ 210 display: "flex", 211 flexDirection: "column", 212 flexGrow: 1, 213 width: '100%' 214 }} 215 > 216 {image.summary.map(l => ( 217 <div 218 style={{ 219 width: "100%", 220 marginBottom: 10 221 }} 222 > 223 {l} 224 </div> 225 ))} 226 </div>)} 227 <div 228 style={{ 229 textAlign: "right", 230 fontSize: 18, 231 display: "flex", 232 justifyContent: "flex-end", 233 alignItems: "center", 234 color: theme.accent2 235 }} 236 > 237 {image.props.get("wordcount") === 'true' && `${image.words} words • `}{(image.props.get("chapters") === 'true' && image.chapterCount !== null) && `${image.chapterCount} chapters • `}https://archiveofourown.org/{addr} 238 </div> 239 </div> 240 </div> 241 ), 242 opts 243 ) 244}