diff --git a/api/render-social-image/[pageId].ts b/api/render-social-image/[pageId].ts deleted file mode 100644 index 52c3267..0000000 --- a/api/render-social-image/[pageId].ts +++ /dev/null @@ -1,129 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next' -import chromium from 'chrome-aws-lambda' -import renderSocialImage from 'puppeteer-social-image-transitive-bs' -import { getBlockTitle, parsePageId } from 'notion-utils' - -import { mapNotionImageUrl } from '../../lib/map-image-url' -// import { getPageDescription } from '../../lib/get-page-description' -import { getPage } from '../../lib/notion' -import * as types from '../../lib/types' -import { - socialImageTitle, - // socialImageSubtitle, - defaultPageCover, - defaultPageIcon, - rootNotionPageId, - socialImageSubtitle -} from '../../lib/config' - -export interface SocialImageConfig { - title: string - subtitle?: string - eyebrow?: string - logo?: string - imageUrl?: string - unsplashId?: string - unsplashKeywords?: string - backgroundImageAnchor?: string - backgroundImageOverlay?: boolean - background?: string - color?: string - googleFont?: string - fontFamily?: string - watermark?: string - size?: - | 'facebook' - | 'twitter' - | 'ig-landscape' - | 'ig-portrait' - | 'ig-square' - | 'ig-story' -} - -export default async (req: NextApiRequest, res: NextApiResponse) => { - if (req.method !== 'GET') { - return res.status(405).send({ error: 'method not allowed' }) - } - - const pageId = req.query.pageId as string - - if (!pageId) { - return res.status(400).send({ error: 'missing required parameter pageId' }) - } - - let recordMap: types.ExtendedRecordMap - let block: types.PageBlock - - try { - recordMap = await getPage(pageId) - - const pageBlockId = Object.keys(recordMap.block)[0] - block = recordMap.block[pageBlockId]?.value as types.PageBlock - - if (!block) { - return res.status(404).send({ - error: `unable to resolve root block for notion page "${pageId}"` - }) - } - } catch (err) { - return res - .status(404) - .send({ error: `unable to load notion page "${pageId}"` }) - } - - const isRootPage = parsePageId(block.id) === parsePageId(rootNotionPageId) - - const image = await createSocialImage({ - imageUrl: mapNotionImageUrl( - block.format?.page_cover || defaultPageCover, - block - ), - logo: mapNotionImageUrl(defaultPageIcon, block), - title: isRootPage - ? socialImageTitle - : getBlockTitle(block, recordMap) || socialImageTitle, - subtitle: isRootPage ? socialImageSubtitle : undefined - // subtitle: getPageDescription(block, recordMap) || socialImageSubtitle - }) - - res.setHeader( - 'Cache-Control', - 'public, immutable, s-maxage=31536000, max-age=31536000, stale-while-revalidate=60' - ) - res.setHeader('Content-Type', 'image/jpeg') - res.status(200).send(image) -} - -async function createSocialImage(params: SocialImageConfig) { - let browser - - try { - // add font support for emojis - // @see https://github.com/alixaxel/chrome-aws-lambda#fonts - await chromium.font( - 'https://raw.githack.com/googlei18n/noto-emoji/master/fonts/NotoColorEmoji.ttf' - ) - - browser = await chromium.puppeteer.launch({ - args: chromium.args, - defaultViewport: chromium.defaultViewport, - executablePath: await chromium.executablePath, - headless: true, // chromium.headless, - ignoreHTTPSErrors: true - }) - - const res = await renderSocialImage({ - template: 'article', - templateParams: params, - templateStyles: `h1 { font-size: 96px; text-align: center; } h2 { margin-top: 48px; font-size: 48px; text-align: center; }`, - size: params.size, - browser - }) - - return res - } finally { - if (browser) { - await browser.close() - } - } -} diff --git a/components/NotionPage.tsx b/components/NotionPage.tsx index fa2b77e..c43e00c 100644 --- a/components/NotionPage.tsx +++ b/components/NotionPage.tsx @@ -126,11 +126,10 @@ export const NotionPage: React.FC = ({ const showTableOfContents = !!isBlogPost const minTableOfContentsItems = 3 - const socialImage = - mapNotionImageUrl( - (block as PageBlock).format?.page_cover || config.defaultPageCover, - block - ) || config.api.renderSocialImage(pageId) + const socialImage = mapNotionImageUrl( + (block as PageBlock).format?.page_cover || config.defaultPageCover, + block + ) const socialDescription = getPageDescription(block, recordMap) ?? config.description diff --git a/lib/config.ts b/lib/config.ts index ced2973..f25d130 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -106,8 +106,7 @@ export const apiBaseUrl = `${host}/api` export const api = { createPreviewImage: `${apiBaseUrl}/create-preview-image`, - searchNotion: `${apiBaseUrl}/search-notion`, - renderSocialImage: (pageId) => `${apiBaseUrl}/render-social-image/${pageId}` + searchNotion: `${apiBaseUrl}/search-notion` } // ---------------------------------------------------------------------------- diff --git a/package.json b/package.json index 1619b1d..d9fd9e1 100644 --- a/package.json +++ b/package.json @@ -41,8 +41,6 @@ "notion-utils": "^4.4.0", "p-map": "^4.0.0", "p-memoize": "^4.0.0", - "puppeteer-core": "^5.5.0", - "puppeteer-social-image-transitive-bs": "^0.8.2", "react": "^17.0.2", "react-body-classname": "^1.3.1", "react-dom": "^17.0.2", @@ -74,7 +72,6 @@ "eslint-plugin-react": "^7.23.1", "npm-run-all": "^4.1.5", "prettier": "^2.0.5", - "puppeteer": "^5.5.0", "typescript": "^4.1.3" } } diff --git a/readme.md b/readme.md index 0d4510f..c47f4f9 100644 --- a/readme.md +++ b/readme.md @@ -143,17 +143,6 @@ The actual work happens in the [create-preview-image](./api/create-preview-image Open Graph images like this one will be generated for each page of your site automatically based each page's content. -By default, it takes into account: - -- cover image (falling back to a default site-wide cover image) -- page icon (falling back to a default site-wide icon) -- page title -- page subtitle (optional; pulled from the "Description" property of collection pages) - -This feature works by rendering some custom HTML to a [Puppeteer](https://pptr.dev) instance in this [serverless function](./api/render-social-image/[pageId].ts) that takes in the page ID as input. - -Here's an example of a social image URL in production: [/api/render-social-image/71201624b204481f862630ea25ce62fe](https://transitivebullsh.it/api/render-social-image/71201624b204481f862630ea25ce62fe) - Note that you shouldn't have to do anything extra to enable this feature as long as you're deploying to Vercel. ### Automatic Table of Contents