nuuklu blog
December 12, 2023
In my previous article, I explained how you can add a static card to Next.js
Having a dynamic card of the content we share will attract more attention on social media thus It will allow us to get more traffic to our site. In this article, I will write how you can add your ogimages that are created dynamically for your Next.js App Router application.
I recommend you to check Next.js' documentation on the subject
If you need a dynamic structure, you are most likely requesting an api. For this example, let’s send a request to jsonplaceholder site and create the opengraph image of our site according to the response
I will show through example
Link of the GitHub RepoLet me show you the file structure
├── src/
└── app/
│ └──users/
│ └──[id]/
│ └──opengraph-image.tsx
│ └──page.tsx
└──lib/
└──userFunctions.ts
I wrote the part where I made the API request in a different file. user Functions.ts
//src/lib/userFunctions.ts
import { User, Users } from "@/types/user";
export const getAllUsers = async (): Promise<Users> => {
let allUsers = await fetch("https://jsonplaceholder.typicode.com/users");
let allUsersJson = await allUsers.json();
return allUsersJson;
};
export const getUserByID = async (id: string): Promise<User> => {
let users = await getAllUsers();
let user = users.find((user) => user.id.toString() == id);
if (!user) throw new Error("no user found with this id: ");
return user;
};
By reading the Next.js documentation, I made both the ‘alt’ description on the photos and the text on my social card dynamic.
// generatedynamicogimages/src/app/users/[id]/opengraph-image.tsx
import { ImageResponse } from "next/og";
import { getUserByID } from "@/lib/userFunctions";
export const runtime = "edge";
export const size = {
width: 1200,
height: 630,
};
export async function generateImageMetadata({
params,
}: {
params: { id: string };
}) {
const user = await getUserByID(params.id);
return [
{
alt: user.address.city,
contentType: "image/png",
},
];
}
export default async function Image({ params }: { params: { id: string } }) {
const user = await getUserByID(params.id);
return new ImageResponse(
(
<div
style={{
fontSize: 48,
background: "white",
width: "100%",
height: "100%",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
{user.phone}
</div>
),
{
...size,
}
);
}