diff --git a/apps/marketing/src/app/(marketing)/blog/[post]/opengraph-image.tsx b/apps/marketing/src/app/(marketing)/blog/[post]/opengraph-image.tsx new file mode 100644 index 000000000..f9987dd27 --- /dev/null +++ b/apps/marketing/src/app/(marketing)/blog/[post]/opengraph-image.tsx @@ -0,0 +1,76 @@ +import { ImageResponse } from 'next/server'; + +import { allBlogPosts } from 'contentlayer/generated'; + +export const runtime = 'edge'; + +export const size = { + width: 1200, + height: 630, +}; + +export const contentType = 'image/png'; + +type BlogPostOpenGraphImageProps = { + params: { post: string }; +}; + +export default async function BlogPostOpenGraphImage({ params }: BlogPostOpenGraphImageProps) { + const blogPost = allBlogPosts.find((post) => post._raw.flattenedPath === `blog/${params.post}`); + + if (!blogPost) { + return null; + } + + // The long urls are needed for a compiler optimisation on the Next.js side, lifting this up + // to a constant will break og image generation. + const [interBold, interRegular, backgroundImage, logoImage] = await Promise.all([ + fetch(new URL('./../../../../assets/inter-bold.ttf', import.meta.url)).then(async (res) => + res.arrayBuffer(), + ), + fetch(new URL('./../../../../assets/inter-regular.ttf', import.meta.url)).then(async (res) => + res.arrayBuffer(), + ), + fetch(new URL('./../../../../assets/background-blog-og.png', import.meta.url)).then( + async (res) => res.arrayBuffer(), + ), + fetch(new URL('./../../../../../public/logo.png', import.meta.url)).then(async (res) => + res.arrayBuffer(), + ), + ]); + + return new ImageResponse( + ( +
+ {/* @ts-expect-error Lack of typing from ImageResponse */} + og-background + + {/* @ts-expect-error Lack of typing from ImageResponse */} + logo + +

+ {blogPost.title} +

+ +

Written by {blogPost.authorName}

+
+ ), + { + ...size, + fonts: [ + { + name: 'Inter', + data: interRegular, + style: 'normal', + weight: 400, + }, + { + name: 'Inter', + data: interBold, + style: 'normal', + weight: 700, + }, + ], + }, + ); +} diff --git a/apps/marketing/src/app/(marketing)/blog/[post]/page.tsx b/apps/marketing/src/app/(marketing)/blog/[post]/page.tsx index 5192dec32..7edf29ec2 100644 --- a/apps/marketing/src/app/(marketing)/blog/[post]/page.tsx +++ b/apps/marketing/src/app/(marketing)/blog/[post]/page.tsx @@ -17,7 +17,9 @@ export const generateMetadata = ({ params }: { params: { post: string } }) => { notFound(); } - return { title: `Documenso - ${blogPost.title}` }; + return { + title: `Documenso - ${blogPost.title}`, + }; }; const mdxComponents: MDXComponents = { diff --git a/apps/marketing/src/assets/background-blog-og.png b/apps/marketing/src/assets/background-blog-og.png new file mode 100644 index 000000000..d5d48a21a Binary files /dev/null and b/apps/marketing/src/assets/background-blog-og.png differ diff --git a/apps/marketing/src/assets/inter-bold.ttf b/apps/marketing/src/assets/inter-bold.ttf new file mode 100644 index 000000000..8e82c70d1 Binary files /dev/null and b/apps/marketing/src/assets/inter-bold.ttf differ diff --git a/apps/marketing/src/assets/inter-regular.ttf b/apps/marketing/src/assets/inter-regular.ttf new file mode 100644 index 000000000..8d4eebf20 Binary files /dev/null and b/apps/marketing/src/assets/inter-regular.ttf differ diff --git a/package-lock.json b/package-lock.json index 12c957494..1fa10b764 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16319,6 +16319,7 @@ } }, "packages/ee": { + "name": "@documenso/ee", "version": "1.0.0", "license": "COMMERCIAL", "dependencies": { @@ -16362,7 +16363,7 @@ "packages/lib": { "name": "@documenso/lib", "version": "1.0.0", - "license": "SEE LICENSE IN LICENSE", + "license": "MIT", "dependencies": { "@documenso/email": "*", "@documenso/prisma": "*",