Skip to content

Commit 4e8d5bf

Browse files
committed
docs: add openGraph and twitter images to metadata for enhanced sharing
1 parent c2864c7 commit 4e8d5bf

File tree

3 files changed

+133
-0
lines changed

3 files changed

+133
-0
lines changed

src/app/docs-og/[...slug]/og.tsx

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { ImageResponse } from "next/og"
2+
import type { ReactElement, ReactNode } from "react"
3+
import type { ImageResponseOptions } from "next/dist/compiled/@vercel/og/types"
4+
5+
interface GenerateProps {
6+
title: ReactNode
7+
description?: ReactNode
8+
primaryTextColor?: string
9+
}
10+
11+
export function generateOGImage(options: GenerateProps & ImageResponseOptions): ImageResponse {
12+
const { title, description, primaryTextColor, ...rest } = options
13+
14+
return new ImageResponse(
15+
generate({
16+
title,
17+
description,
18+
primaryTextColor,
19+
}),
20+
{
21+
width: 1200,
22+
height: 630,
23+
...rest,
24+
},
25+
)
26+
}
27+
28+
export function generate({
29+
primaryTextColor = "rgb(255,150,255)",
30+
...props
31+
}: GenerateProps): ReactElement {
32+
return (
33+
<div
34+
style={{
35+
display: "flex",
36+
flexDirection: "column",
37+
width: "100%",
38+
height: "100%",
39+
color: "white",
40+
backgroundColor: "rgb(10,10,10)",
41+
}}
42+
>
43+
<div
44+
style={{
45+
display: "flex",
46+
flexDirection: "column",
47+
width: "100%",
48+
height: "100%",
49+
padding: "4rem",
50+
}}
51+
>
52+
<p
53+
style={{
54+
fontWeight: 600,
55+
fontSize: "76px",
56+
}}
57+
>
58+
{props.title}
59+
</p>
60+
<p
61+
style={{
62+
fontSize: "48px",
63+
color: "rgba(240,240,240,0.7)",
64+
}}
65+
>
66+
{props.description}
67+
</p>
68+
<div
69+
style={{
70+
display: "flex",
71+
flexDirection: "row",
72+
alignItems: "center",
73+
gap: "24px",
74+
marginTop: "auto",
75+
color: primaryTextColor,
76+
}}
77+
>
78+
<img
79+
src={`${process.env.NEXT_PUBLIC_BASE_URL}/logo.png`}
80+
width="60"
81+
height="60"
82+
alt="Logo"
83+
/>
84+
<p
85+
style={{
86+
fontSize: "46px",
87+
fontWeight: 600,
88+
}}
89+
>
90+
TheNextLvl
91+
</p>
92+
</div>
93+
</div>
94+
</div>
95+
)
96+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { generateOGImage } from "./og"
2+
import { source } from "@/lib/source"
3+
import { notFound } from "next/navigation"
4+
5+
export async function GET(_req: Request, { params }: { params: Promise<{ slug: string[] }> }) {
6+
const { slug } = await params
7+
const page = source.getPage(slug.slice(0, -1))
8+
if (!page) notFound()
9+
10+
return generateOGImage({
11+
primaryTextColor: "rgb(240,240,240)",
12+
title: page.data.title,
13+
description: page.data.description,
14+
})
15+
}
16+
17+
export function generateStaticParams(): {
18+
slug: string[]
19+
}[] {
20+
return source.generateParams().map((page) => ({
21+
...page,
22+
slug: [...page.slug, "image.png"],
23+
}))
24+
}

src/app/docs/[[...slug]]/page.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,21 @@ export async function generateMetadata(props: { params: Promise<{ slug?: string[
5454
const page = source.getPage(params.slug)
5555
if (!page) notFound()
5656

57+
const image = {
58+
url: ["/docs-og", ...(params.slug || []), "image.png"].join("/"),
59+
width: 1200,
60+
height: 630,
61+
}
62+
5763
return {
5864
title: page.data.title,
5965
description: page.data.description,
66+
openGraph: {
67+
images: image,
68+
},
69+
twitter: {
70+
card: "summary_large_image",
71+
images: image,
72+
},
6073
}
6174
}

0 commit comments

Comments
 (0)