mirror of
https://github.com/r-freeman/portfolio.git
synced 2024-11-23 02:55:41 +00:00
Ryan Freeman
40913ad401
All checks were successful
Build And Publish / BuildAndPublish (push) Successful in 2m43s
139 lines
5.4 KiB
Plaintext
139 lines
5.4 KiB
Plaintext
import {ArticleLayout} from '../../../components/layouts/ArticleLayout'
|
||
import {createSlug} from '../../../lib/createSlug'
|
||
import Image from 'next/image'
|
||
import ogMetaTags from './open-graph-meta-tags.png'
|
||
import {metadata as _metadata} from '../../../lib/generateMetadata'
|
||
|
||
export const meta = {
|
||
authors: 'Ryan Freeman',
|
||
title: 'Generating dynamic Open Graph images with Next.js',
|
||
date: '2024-10-10',
|
||
description: 'In this post I\'ll talk about how I created dynamic, eye-catching Open Graph images with Next.js for this website.',
|
||
alternates: {
|
||
canonical: `/writing/${createSlug('Generating dynamic Open Graph images with Next.js')}`
|
||
}
|
||
}
|
||
|
||
export const metadata = _metadata({
|
||
title: meta.title,
|
||
heading: meta.title,
|
||
description: meta.description,
|
||
type: 'article',
|
||
alternates: meta.alternates
|
||
})
|
||
|
||
export default (props) => <ArticleLayout
|
||
title={meta.title}
|
||
date={meta.date}
|
||
description={meta.description}
|
||
slug={createSlug(meta.title)}
|
||
{...props} />
|
||
|
||
In this post I\'ll talk about how I created dynamic, eye-catching Open Graph images with Next.js for this website.
|
||
|
||
## What is Open Graph?
|
||
|
||
[Open Graph](https://ogp.me/) is the web standard that allows website owners to manage the appearance of their content when it is shared on social media platforms.
|
||
|
||
In other words, it enables website owners to attract readers to their content, similar to how thumbnails on YouTube videos attract our attention and entice us to click on a video.
|
||
|
||
## Show me the code
|
||
|
||
Alright, let\'s see how this was achieved in code. Taking the new [Services page](/services) as an example, the first step was to create a new API route located at `/api/og-image`.
|
||
|
||
### API route
|
||
|
||
This API route should allow me to specify some text like a page heading and dynamically generate an image, which I can then reference using the Open Graph meta tags on each page.
|
||
|
||
```javascript
|
||
export async function GET(request: Request) {
|
||
const { searchParams } = new URL(request.url)
|
||
const text = searchParams.get('text')
|
||
```
|
||
|
||
This was straightforward to implement, here the API route responds to a `GET` request and accepts a `text` parameter in the url. For example, `/api/og-image?text=hello,world`.
|
||
|
||
```javascript
|
||
return new ImageResponse(
|
||
(
|
||
<div
|
||
style={{
|
||
fontSize: 64,
|
||
background: 'black',
|
||
width: '100%',
|
||
height: '100%',
|
||
display: 'flex',
|
||
textAlign: 'center',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
lineHeight: '1',
|
||
padding: '0 128px'
|
||
}}
|
||
>
|
||
<div
|
||
style={{
|
||
backgroundImage: 'radial-gradient(at right top, rgb(221, 214, 254), rgb(239, 68, 68), rgb(251, 146, 60))',
|
||
backgroundClip: 'text',
|
||
// @ts-ignore
|
||
'-webkit-background-clip': 'text',
|
||
color: 'transparent'
|
||
}}>
|
||
{text}
|
||
</div>
|
||
</div>
|
||
),
|
||
{
|
||
width: 1200,
|
||
height: 600
|
||
}
|
||
)
|
||
```
|
||
|
||
Next, I thought about how I wanted the Open Graph image to look. To keep things simple, I settled on a black background with the text centered both horizontally and vertically.
|
||
|
||
This was achieved using the [ImageReponse](https://nextjs.org/docs/app/api-reference/functions/image-response) constructor, which allows you to create and style dynamic images using JSX and CSS.
|
||
|
||
<Image src={`/api/og-image?text=hello,world`} width="1200" height="600" alt=""/>
|
||
|
||
When you visit the API route and specify some text in the url, you'll get something that looks like the image above. Next, I'll demonstrate how I added the Open Graph meta tags to the Services page to render this dynamic image for social media platforms.
|
||
|
||
### Open Graph Meta Tags
|
||
|
||
The last step was to include the Open Graph meta tags on the Services page so that when it's shared, an eye-catching image will appear to draw readers to the content.
|
||
|
||
```javascript
|
||
const meta = {
|
||
title: 'Services - Ryan Freeman',
|
||
heading: 'I offer a wide range of digital services to elevate and transform your business',
|
||
description: 'Whether you need a WordPress website, React app, AWS support or odd coding jobs, I\'m here to help. ' +
|
||
'As an experienced software engineer, I produce high-quality software that will deliver immediate value for you and your customers.',
|
||
}
|
||
|
||
export const metadata = {
|
||
...meta,
|
||
openGraph: {
|
||
title: meta.title,
|
||
description: meta.description,
|
||
images: [
|
||
{
|
||
url: `/api/og-image?text=${meta.heading}`,
|
||
width: 1200,
|
||
height: 600,
|
||
alt: meta.heading,
|
||
type: 'image/png'
|
||
}
|
||
],
|
||
type: 'website'
|
||
}
|
||
}
|
||
```
|
||
|
||
By exporting the `metadata` object, I was able to specify the Open Graph meta tags for this page. In this example, you can see how I’m fetching data from the new API route, which generates a dynamic image featuring the page heading, sized at 1200 by 600 pixels.
|
||
|
||
<Image src={ogMetaTags} alt=""/>
|
||
|
||
Lastly, I can verify everything is working correctly by loading the Services page in the browser and examining the Open Graph meta tags.
|
||
|
||
## Conclusion
|
||
|
||
In this post, I demonstrated how you can create dynamic Open Graph images with Next.js for creating content previews which engage readers and attract them to your content. |