From fa0f379279c31a61afcd8f52acbba96a04818058 Mon Sep 17 00:00:00 2001 From: HopeFullee Date: Thu, 1 Jan 2026 23:19:00 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=AA=A8=EC=9E=84=EC=83=81=EC=84=B8=20?= =?UTF-8?q?meta=20=EB=B0=8F=20OG=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/group/[groupId]/layout.tsx | 6 +++ src/lib/metadata/group.ts | 75 ++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 src/lib/metadata/group.ts diff --git a/src/app/group/[groupId]/layout.tsx b/src/app/group/[groupId]/layout.tsx index 2f17fe37..0eb9d962 100644 --- a/src/app/group/[groupId]/layout.tsx +++ b/src/app/group/[groupId]/layout.tsx @@ -2,6 +2,7 @@ import { dehydrate, HydrationBoundary } from '@tanstack/react-query'; import { QueryClient } from '@tanstack/react-query'; import { API } from '@/api'; +import { generateGroupMetadata } from '@/lib/metadata/group'; import { groupKeys } from '@/lib/query-key/query-key-group'; interface Props { @@ -9,6 +10,11 @@ interface Props { params: Promise<{ groupId: string }>; } +export const generateMetadata = async ({ params }: Props) => { + const { groupId } = await params; + return await generateGroupMetadata(groupId); +}; + const GroupDetailLayout = async ({ children, params }: Props) => { const { groupId } = await params; diff --git a/src/lib/metadata/group.ts b/src/lib/metadata/group.ts new file mode 100644 index 00000000..8afa1cdd --- /dev/null +++ b/src/lib/metadata/group.ts @@ -0,0 +1,75 @@ +import { Metadata } from 'next'; +import { headers } from 'next/headers'; + +import { API } from '@/api'; + +export const generateGroupMetadata = async (groupId: string): Promise => { + const headersList = headers(); + const host = (await headersList).get('host') || process.env.DOMAIN; + const currentUrl = `https://${host}/group/${groupId}`; + + try { + const { + createdBy: { nickName }, + title, + images, + } = await API.groupService.getGroupDetails({ groupId }); + + const metaTitle = `${nickName}님의 모임 | WeGo`; + const metaDescription = title; + + const thumbnails = images[0]?.variants ? images[0].variants[0].imageUrl : ''; + + return { + title: metaTitle, + description: metaDescription, + keywords: [nickName, '모임', 'WeGo'], + openGraph: { + title: metaTitle, + description: metaDescription, + siteName: 'WeGo', + locale: 'ko_KR', + type: 'website', + url: currentUrl, + images: thumbnails + ? [ + { + url: thumbnails, + width: 400, + height: 400, + alt: `${nickName}님의 모임 사진`, + }, + ] + : [], + }, + twitter: { + card: 'summary', + title: metaTitle, + description: metaDescription, + images: thumbnails ? [thumbnails] : undefined, + }, + robots: { + index: true, + follow: true, + }, + alternates: { + canonical: currentUrl, + }, + }; + } catch (error) { + console.error('Failed to fetch group data for metadata:', error); + return { + title: `모임 상세 정보 | WeGo`, + description: '사용자의 모임을 확인해보세요.', + openGraph: { + title: '사용자 모임 | WeGo', + description: '사용자의 모임을 확인해보세요.', + url: currentUrl, + type: 'website', + }, + twitter: { + card: 'summary', + }, + }; + } +};