-
Notifications
You must be signed in to change notification settings - Fork 160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't let opengraph image embeds go stale #2765
base: main
Are you sure you want to change the base?
Changes from 3 commits
28f7a45
ca564e4
7d15c1b
ab57173
ba5a945
2fa1e0b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
diff --git a/node_modules/lodash/_root.js b/node_modules/lodash/_root.js | ||
index d2852be..aa44a86 100644 | ||
--- a/node_modules/lodash/_root.js | ||
+++ b/node_modules/lodash/_root.js | ||
@@ -4,6 +4,6 @@ var freeGlobal = require('./_freeGlobal'); | ||
var freeSelf = typeof self == 'object' && self && self.Object === Object && self; | ||
|
||
/** Used as a reference to the global object. */ | ||
-var root = freeGlobal || freeSelf || Function('return this')(); | ||
+var root = freeGlobal || freeSelf; | ||
|
||
module.exports = root; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,12 +3,15 @@ import { ImageResponseOptions } from '@vercel/og/dist/types' | |
import { NextRequest } from 'next/server' | ||
import { OgMarket } from 'web/components/og/og-market' | ||
import { classToTw } from 'web/components/og/utils' | ||
import { OgCardProps } from 'common/contract-seo' | ||
import { getContractOGProps, OgCardProps } from 'common/contract-seo' | ||
import { getContract } from 'common/supabase/contracts' | ||
import { db } from 'web/lib/supabase/db' | ||
|
||
export const config = { runtime: 'edge' } | ||
export const getCardOptions = async () => { | ||
export const getCardOptions = async (): Promise<ImageResponseOptions> => { | ||
const [light, med] = await Promise.all([figtreeLightData, figtreeMediumData]) | ||
|
||
// https://vercel.com/docs/functions/og-image-generation/og-image-api | ||
return { | ||
width: 600, | ||
height: 315, | ||
|
@@ -24,6 +27,11 @@ export const getCardOptions = async () => { | |
style: 'normal', | ||
}, | ||
], | ||
headers: { | ||
// max-age is in seconds. Vercel defaults to a very large value, but | ||
// we want to show fresh data, so we override here. | ||
'cache-control': 'public, no-transform, max-age=30', | ||
}, | ||
} | ||
} | ||
|
||
|
@@ -36,16 +44,38 @@ const figtreeMediumData = fetch(FIGTREE_MED_URL).then((res) => | |
res.arrayBuffer() | ||
) | ||
|
||
async function getFreshOgMarketProps( | ||
contractId: string | undefined | ||
): Promise<OgCardProps | undefined> { | ||
if (contractId) { | ||
try { | ||
const contract = await getContract(db, contractId) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It think it would be simpler to just use the public api to fetch the contract rather than use the internal api. That way we don't have to patch lodash, either. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wasn't aware of the public API, thanks for the pointer. |
||
if (contract) { | ||
return getContractOGProps(contract) | ||
} | ||
} catch (e) { | ||
console.log( | ||
'Failed to fetch contract ${contractId} when rendering OG image', | ||
e | ||
) | ||
} | ||
} | ||
return undefined | ||
} | ||
|
||
export default async function handler(req: NextRequest) { | ||
try { | ||
const { searchParams } = new URL(req.url) | ||
const options = await getCardOptions() | ||
const OgMarketProps = Object.fromEntries( | ||
const ogMarketPropsFromParams = Object.fromEntries( | ||
searchParams.entries() | ||
) as OgCardProps | ||
const image = OgMarket(OgMarketProps) | ||
const { contractId } = ogMarketPropsFromParams | ||
const ogMarketPropsFromDb = await getFreshOgMarketProps(contractId) | ||
|
||
const image = OgMarket(ogMarketPropsFromDb ?? ogMarketPropsFromParams) | ||
|
||
return new ImageResponse(classToTw(image), options as ImageResponseOptions) | ||
return new ImageResponse(classToTw(image), options) | ||
} catch (e: any) { | ||
console.log(`${e.message}`) | ||
return new Response(`Failed to generate the image`, { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, so when are we're supposed to run this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It runs automatically as part of the installation lifecycle, apparently: https://yarnpkg.com/advanced/lifecycle-scripts#postinstall
But moot point if we're going with the public API.