Skip to content

Commit e717a38

Browse files
committed
fix: add presence test for OG image assets
1 parent 70374e9 commit e717a38

File tree

2 files changed

+57
-28
lines changed

2 files changed

+57
-28
lines changed

pages/api/notion-page-info.tsx

+50-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { NextApiRequest, NextApiResponse } from 'next'
22

3+
import got from 'got'
34
import { PageBlock } from 'notion-types'
45
import {
56
getBlockIcon,
@@ -48,24 +49,6 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
4849
const isBlogPost =
4950
block.type === 'page' && block.parent_table === 'collection'
5051
const title = getBlockTitle(block, recordMap) || libConfig.name
51-
let image = mapImageUrl(
52-
getPageProperty<string>('Social Image', block, recordMap) ||
53-
(block as PageBlock).format?.page_cover ||
54-
libConfig.defaultPageCover,
55-
block
56-
)
57-
58-
if (image) {
59-
const imageUrl = new URL(image)
60-
61-
if (imageUrl.host === 'images.unsplash.com') {
62-
if (!imageUrl.searchParams.has('w')) {
63-
imageUrl.searchParams.set('w', '1200')
64-
imageUrl.searchParams.set('fit', 'max')
65-
image = imageUrl.toString()
66-
}
67-
}
68-
}
6952

7053
const imageCoverPosition =
7154
(block as PageBlock).format?.page_cover_position ??
@@ -74,11 +57,23 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
7457
? `center ${(1 - imageCoverPosition) * 100}%`
7558
: null
7659

60+
const imageBlockUrl = mapImageUrl(
61+
getPageProperty<string>('Social Image', block, recordMap) ||
62+
(block as PageBlock).format?.page_cover,
63+
block
64+
)
65+
const imageFallbackUrl = mapImageUrl(libConfig.defaultPageCover, block)
66+
7767
const blockIcon = getBlockIcon(block, recordMap)
78-
const authorImage = mapImageUrl(
79-
blockIcon && isUrl(blockIcon) ? blockIcon : libConfig.defaultPageIcon,
68+
const authorImageBlockUrl = mapImageUrl(
69+
blockIcon && isUrl(blockIcon) ? blockIcon : null,
8070
block
8171
)
72+
const authorImageFallbackUrl = mapImageUrl(libConfig.defaultPageIcon, block)
73+
const [authorImage, image] = await Promise.all([
74+
getCompatibleImageUrl(authorImageBlockUrl, authorImageFallbackUrl),
75+
getCompatibleImageUrl(imageBlockUrl, imageFallbackUrl)
76+
])
8277

8378
const author =
8479
getPageProperty<string>('Author', block, recordMap) || libConfig.author
@@ -119,7 +114,41 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
119114

120115
res.setHeader(
121116
'Cache-Control',
122-
'public, s-maxage=30, max-age=30, stale-while-revalidate=30'
117+
'public, s-maxage=3600, max-age=3600, stale-while-revalidate=3600'
123118
)
124119
res.status(200).json(pageInfo)
125120
}
121+
122+
async function isUrlReachable(url: string | null): Promise<boolean> {
123+
if (!url) {
124+
return false
125+
}
126+
127+
try {
128+
await got.head(url)
129+
return true
130+
} catch (err) {
131+
return false
132+
}
133+
}
134+
135+
async function getCompatibleImageUrl(
136+
url: string | null,
137+
fallbackUrl: string | null
138+
): Promise<string | null> {
139+
const image = (await isUrlReachable(url)) ? url : fallbackUrl
140+
141+
if (image) {
142+
const imageUrl = new URL(image)
143+
144+
if (imageUrl.host === 'images.unsplash.com') {
145+
if (!imageUrl.searchParams.has('w')) {
146+
imageUrl.searchParams.set('w', '1200')
147+
imageUrl.searchParams.set('fit', 'max')
148+
return imageUrl.toString()
149+
}
150+
}
151+
}
152+
153+
return image
154+
}

pages/api/social-image.tsx

+7-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { NextRequest } from 'next/server'
33

44
import { ImageResponse } from '@vercel/og'
55

6-
import { api, apiHost } from '@/lib/config'
6+
import { api, apiHost, rootNotionPageId } from '@/lib/config'
77
import { NotionPageInfo } from '@/lib/types'
88

99
const interRegularFontP = fetch(
@@ -19,13 +19,8 @@ export const config = {
1919
}
2020

2121
export default async function OGImage(req: NextRequest) {
22-
const [interRegularFont, interBoldFont] = await Promise.all([
23-
interRegularFontP,
24-
interBoldFontP
25-
])
26-
2722
const { searchParams } = new URL(req.url)
28-
const pageId = searchParams.get('id')
23+
const pageId = searchParams.get('id') || rootNotionPageId
2924
if (!pageId) {
3025
return new Response('Invalid notion page id', { status: 400 })
3126
}
@@ -43,6 +38,11 @@ export default async function OGImage(req: NextRequest) {
4338
const pageInfo: NotionPageInfo = await pageInfoRes.json()
4439
console.log(pageInfo)
4540

41+
const [interRegularFont, interBoldFont] = await Promise.all([
42+
interRegularFontP,
43+
interBoldFontP
44+
])
45+
4646
return new ImageResponse(
4747
(
4848
<div

0 commit comments

Comments
 (0)