Skip to content

Commit

Permalink
Open graph dynamic image generation (#6357)
Browse files Browse the repository at this point in the history
Co-authored-by: Claudio Wunder <[email protected]>
  • Loading branch information
bmuenzenmeyer and ovflowd authored Mar 1, 2024
1 parent fe93dd6 commit dd4cadc
Show file tree
Hide file tree
Showing 7 changed files with 1,519 additions and 3 deletions.
67 changes: 67 additions & 0 deletions app/[locale]/next-data/og/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { ImageResponse } from 'next/og';

import HexagonGrid from '@/components/Icons/HexagonGrid';
import JsIconWhite from '@/components/Icons/Logos/JsIconWhite';
import { ENABLE_STATIC_EXPORT, VERCEL_REVALIDATE } from '@/next.constants.mjs';
import { defaultLocale } from '@/next.locales.mjs';
import tailwindConfig from '@/tailwind.config';
import { hexToRGBA } from '@/util/hexToRGBA';

// This is the Route Handler for the `GET` method which handles the request
// for generating OpenGrapgh images for Blog Posts and Pages
// @see https://nextjs.org/docs/app/building-your-application/routing/router-handlers
export const GET = async (request: Request) => {
const { searchParams } = new URL(request.url);

// ?title=<title>
const hasTitle = searchParams.has('title');
const title = hasTitle ? searchParams.get('title')?.slice(0, 100) : undefined;

//?type=<type>
const type = searchParams.get('type') ?? 'announcement';

const typeAttributes: { [key: string]: string } = {
announcement: tailwindConfig.theme.colors.green['700'],
release: tailwindConfig.theme.colors.info['600'],
vulnerability: tailwindConfig.theme.colors.warning['600'],
};

const gridBackground = `radial-gradient(circle, ${hexToRGBA(typeAttributes[type])}, transparent)`;

return new ImageResponse(
(
<div tw="relative flex items-center justify-center bg-black w-[1200px] h-[600px]">
<HexagonGrid style={{ background: gridBackground }} />

<div tw="absolute mx-auto flex max-w-xl flex-col text-center text-3xl font-semibold text-white">
<JsIconWhite width={71} height={80} tw="mx-auto" />

<h2>{title}</h2>
</div>
</div>
),
{ width: 1200, height: 600 }
);
};

// This route is fully dynamic hence there shouldn't be any static param
// available to ensure that the route is not statically generated
export const generateStaticParams = async () => [
{ locale: defaultLocale.code },
];

// We want to use `edge` runtime when using Vercel
export const runtime = process.env.NEXT_PUBLIC_VERCEL_URL ? 'edge' : false;

// Enforces that only the paths from `generateStaticParams` are allowed, giving 404 on the contrary
// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamicparams
export const dynamicParams = true;

// Enforces that this route is used as static rendering
// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic
export const dynamic = ENABLE_STATIC_EXPORT ? 'force-static' : 'auto';

// Ensures that this endpoint is invalidated and re-executed every X minutes
// so that when new deployments happen, the data is refreshed
// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#revalidate
export const revalidate = VERCEL_REVALIDATE;
Loading

0 comments on commit dd4cadc

Please sign in to comment.