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}