nuuklu blog
12 Aralık 2023
Bir önceki yazımda Next.js’e nasıl statik kart ekleyebileceğinizi aktarmıştım.
Paylaştığımız içeriğin dinamik bir kartının olması sosyal medyada daha fazla ilgi çekeceğinden; sitemize daha fazla trafik almamızı sağlayacaktır. Bu yazıda Next.js App Router uygulamanıza dinamik olarak kartınızı nasıl ekleyebileceğimizi yazacağım.
Next.js'in konuyla ilgili dökümanını kontrol etmenizi tavsiye ederim
Dinamik bir yapıya ihtiyaç duyuyorsanız çok yüksek ihtimalle bir api‘a istek atıyorsunuzdur. Bu örnek için jsonplaceholder sitesine istek atıp, gelen response’a göre sitemizin opengraph image‘ini oluşturalım.
Örnek üzerinden göstereceğim
Projenin github linkiÖncelikle dosya yapısını ekleyeyim
├── src/
└── app/
│ └──users/
│ └──[id]/
│ └──opengraph-image.tsx
│ └──page.tsx
└──lib/
└──userFunctions.ts
Api’a istek attığım bölümü farklı bir dosyada yazdım. userFunctions.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;
};
Next.js dökümantasyonunu okuyarak hem fotoğraflardaki ‘alt’ açıklamasını hem de sosyal kartımdaki yazıyı dinamik bir hale getirdim.
// 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,
}
);
}