From 0705f901a5378f2ec5fb97ad671baabb3b2cc413 Mon Sep 17 00:00:00 2001 From: Moinul Moin Date: Sat, 6 Jan 2024 17:51:33 +0600 Subject: [PATCH] feat: :sparkles: add og api --- src/app/[locale]/layout.tsx | 15 ++++--- src/app/api/og/route.ts | 32 ++++++++++++++ src/app/{[locale] => }/opengraph-image.tsx | 2 +- src/components/OGImgEl.tsx | 50 ++++++++++++++++++++++ 4 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 src/app/api/og/route.ts rename src/app/{[locale] => }/opengraph-image.tsx (96%) create mode 100644 src/components/OGImgEl.tsx diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx index 56ebac1..3539dc4 100644 --- a/src/app/[locale]/layout.tsx +++ b/src/app/[locale]/layout.tsx @@ -3,8 +3,9 @@ import Footer from "~/components/layout/footer"; import Header from "~/components/layout/header"; import ThemeProvider from "~/components/shared/theme-provider"; import { Toaster } from "~/components/ui/toaster"; -import { siteConfig } from "~/config/site"; +import { siteConfig, siteUrl } from "~/config/site"; import { I18nProviderClient } from "~/locales/client"; +import { getScopedI18n } from "~/locales/server"; type Props = { params: { locale: string }; @@ -12,9 +13,13 @@ type Props = { }; export async function generateMetadata({ params }: Props): Promise { - const locale = params.locale || "en"; + const locale = params.locale; const site = siteConfig(locale); + const t = await getScopedI18n("hero"); + const title = t("main"); + const siteOgImage = `${siteUrl}/api/og?title=${title}`; + return { title: { default: site.name, @@ -42,14 +47,14 @@ export async function generateMetadata({ params }: Props): Promise { creator: "moinulmoin", openGraph: { type: "website", - locale: "en_US", + locale: locale, url: site.url, title: site.name, description: site.description, siteName: site.name, images: [ { - url: site.ogImage, + url: siteOgImage, width: 1200, height: 630, alt: site.name, @@ -60,7 +65,7 @@ export async function generateMetadata({ params }: Props): Promise { card: "summary_large_image", title: site.name, description: site.description, - images: [site.ogImage], + images: [siteOgImage], creator: "@immoinulmoin", }, icons: { diff --git a/src/app/api/og/route.ts b/src/app/api/og/route.ts new file mode 100644 index 0000000..165b78f --- /dev/null +++ b/src/app/api/og/route.ts @@ -0,0 +1,32 @@ +import { ImageResponse } from "next/og"; +import { RenderIMGEl } from "~/components/OGImgEl"; +import Logo from "../../../../public/chad-next.png"; + +export const runtime = "edge"; + +export async function GET(request: Request) { + const { searchParams } = new URL(request.url); + const hasTitle = searchParams.has("title"); + const title = hasTitle + ? searchParams.get("title") + : "Quick Starter Template for your Next project"; + + try { + return new ImageResponse( + RenderIMGEl({ + logo: process.env.NEXT_PUBLIC_APP_URL + Logo.src, + title: title as string, + }), + { + width: 1200, + height: 630, + } + ); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (e: any) { + console.log(`${e.message}`); + return new Response(`Failed to generate the image`, { + status: 500, + }); + } +} diff --git a/src/app/[locale]/opengraph-image.tsx b/src/app/opengraph-image.tsx similarity index 96% rename from src/app/[locale]/opengraph-image.tsx rename to src/app/opengraph-image.tsx index bf915c0..f2dfc5d 100644 --- a/src/app/[locale]/opengraph-image.tsx +++ b/src/app/opengraph-image.tsx @@ -1,7 +1,7 @@ /* eslint-disable @next/next/no-img-element */ import { ImageResponse } from "next/og"; import { getScopedI18n } from "~/locales/server"; -import Logo from "../../../public/chad-next.png"; +import Logo from "../../public/chad-next.png"; export const runtime = "edge"; export const contentType = "image/png"; diff --git a/src/components/OGImgEl.tsx b/src/components/OGImgEl.tsx new file mode 100644 index 0000000..0df854c --- /dev/null +++ b/src/components/OGImgEl.tsx @@ -0,0 +1,50 @@ +/* eslint-disable @next/next/no-img-element */ +export const RenderIMGEl = ({ + logo, + title, +}: { + logo: string; + title: string; +}) => { + return ( +
+ ChadNext Logo +

+ ChadNext +

+

+ {title} +

+
+ ); +};