|
| 1 | +import { ImageResponse } from 'next/og'; |
| 2 | + |
| 3 | +import HexagonGrid from '@/components/Icons/HexagonGrid'; |
| 4 | +import JsIconWhite from '@/components/Icons/Logos/JsIconWhite'; |
| 5 | +import { ENABLE_STATIC_EXPORT, VERCEL_REVALIDATE } from '@/next.constants.mjs'; |
| 6 | +import { defaultLocale } from '@/next.locales.mjs'; |
| 7 | +import tailwindConfig from '@/tailwind.config'; |
| 8 | +import { hexToRGBA } from '@/util/hexToRGBA'; |
| 9 | + |
| 10 | +// This is the Route Handler for the `GET` method which handles the request |
| 11 | +// for generating OpenGrapgh images for Blog Posts and Pages |
| 12 | +// @see https://nextjs.org/docs/app/building-your-application/routing/router-handlers |
| 13 | +export const GET = async (request: Request) => { |
| 14 | + const { searchParams } = new URL(request.url); |
| 15 | + |
| 16 | + // ?title=<title> |
| 17 | + const hasTitle = searchParams.has('title'); |
| 18 | + const title = hasTitle ? searchParams.get('title')?.slice(0, 100) : undefined; |
| 19 | + |
| 20 | + //?type=<type> |
| 21 | + const type = searchParams.get('type') ?? 'announcement'; |
| 22 | + |
| 23 | + const typeAttributes: { [key: string]: string } = { |
| 24 | + announcement: tailwindConfig.theme.colors.green['700'], |
| 25 | + release: tailwindConfig.theme.colors.info['600'], |
| 26 | + vulnerability: tailwindConfig.theme.colors.warning['600'], |
| 27 | + }; |
| 28 | + |
| 29 | + const gridBackground = `radial-gradient(circle, ${hexToRGBA(typeAttributes[type])}, transparent)`; |
| 30 | + |
| 31 | + return new ImageResponse( |
| 32 | + ( |
| 33 | + <div tw="relative flex items-center justify-center bg-black w-[1200px] h-[600px]"> |
| 34 | + <HexagonGrid style={{ background: gridBackground }} /> |
| 35 | + |
| 36 | + <div tw="absolute mx-auto flex max-w-xl flex-col text-center text-3xl font-semibold text-white"> |
| 37 | + <JsIconWhite width={71} height={80} tw="mx-auto" /> |
| 38 | + |
| 39 | + <h2>{title}</h2> |
| 40 | + </div> |
| 41 | + </div> |
| 42 | + ), |
| 43 | + { width: 1200, height: 600 } |
| 44 | + ); |
| 45 | +}; |
| 46 | + |
| 47 | +// This route is fully dynamic hence there shouldn't be any static param |
| 48 | +// available to ensure that the route is not statically generated |
| 49 | +export const generateStaticParams = async () => [ |
| 50 | + { locale: defaultLocale.code }, |
| 51 | +]; |
| 52 | + |
| 53 | +// We want to use `edge` runtime when using Vercel |
| 54 | +export const runtime = process.env.NEXT_PUBLIC_VERCEL_URL ? 'edge' : false; |
| 55 | + |
| 56 | +// Enforces that only the paths from `generateStaticParams` are allowed, giving 404 on the contrary |
| 57 | +// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamicparams |
| 58 | +export const dynamicParams = true; |
| 59 | + |
| 60 | +// Enforces that this route is used as static rendering |
| 61 | +// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic |
| 62 | +export const dynamic = ENABLE_STATIC_EXPORT ? 'force-static' : 'auto'; |
| 63 | + |
| 64 | +// Ensures that this endpoint is invalidated and re-executed every X minutes |
| 65 | +// so that when new deployments happen, the data is refreshed |
| 66 | +// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#revalidate |
| 67 | +export const revalidate = VERCEL_REVALIDATE; |
0 commit comments