From 25f5c00e37d94970b05c1c0d8df8bf41ecaa2e3c Mon Sep 17 00:00:00 2001 From: davidktlee Date: Mon, 1 Apr 2024 15:41:41 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20detail=20=EB=A9=94=ED=83=80=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/[travel]/[id]/page.tsx | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx b/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx index 45c821917..80b1857b3 100644 --- a/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx +++ b/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx @@ -10,6 +10,36 @@ import SpotDetail from '@/app/_components/mypage/spot/SpotDetail'; import { myInfoSchema } from '@/types/response'; import React from 'react'; +export async function generateMetaData({ + params, +}: { + params: { id: number; travel: string }; +}) { + if (params.travel === 'spot') { + const spotDetail = await getSpotDetail(params.id); + if (spotDetail.status === 'succeed') { + return { + title: spotDetail.data.place_name, + description: spotDetail.data.description, + openGraph: { + images: [spotDetail.data.image_urls[0]], + }, + }; + } + } else { + const courseDetail = await getCourseDetail(params.id); + if (courseDetail.status === 'succeed') { + return { + title: courseDetail.data.title, + description: courseDetail.data.description, + openGraph: { + images: [courseDetail.data.map_static_image_url], + }, + }; + } + } +} + export default async function SpotDetailPage({ params, }: { From 8b4855592c5de6b195bf5dcbc1f8e0a18198d349 Mon Sep 17 00:00:00 2001 From: davidktlee Date: Mon, 1 Apr 2024 18:06:37 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=EC=98=A4=ED=94=88=20=EA=B7=B8?= =?UTF-8?q?=EB=9E=98=ED=94=84=20=EC=84=A4=EC=A0=95=20=EB=B0=8F=20reponse?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/public/logo/og-logo.png | Bin 0 -> 15838 bytes .../detail/[travel]/[id]/page.tsx | 34 +++++++++++++----- .../src/app/(with-header)/place/[id]/page.tsx | 2 ++ .../src/app/(without-header)/login/page.tsx | 2 ++ .../_components/mypage/hooks/myPageActions.ts | 2 +- frontend/src/app/layout.tsx | 14 ++++++++ frontend/src/utils.ts | 30 ++++++++++++++++ 7 files changed, 74 insertions(+), 10 deletions(-) create mode 100644 frontend/public/logo/og-logo.png diff --git a/frontend/public/logo/og-logo.png b/frontend/public/logo/og-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4cbf5a094c00e2454a4e05b70dd5f582c9b715bd GIT binary patch literal 15838 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 literal 0 HcmV?d00001 diff --git a/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx b/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx index 34695e448..43f91c517 100644 --- a/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx +++ b/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx @@ -9,34 +9,50 @@ import { import SpotDetail from '@/app/_components/mypage/spot/SpotDetail'; import { myInfoSchema } from '@/types/response'; import React from 'react'; +import { Metadata } from 'next'; +import { createMetadata } from '@/utils'; -export async function generateMetaData({ +export async function generateMetadata({ params, }: { params: { id: number; travel: string }; -}) { +}): Promise { if (params.travel === 'spot') { const spotDetail = await getSpotDetail(params.id); if (spotDetail.status === 'succeed') { - return { + const data = { title: spotDetail.data.place_name, description: spotDetail.data.description, + image: spotDetail.data.image_urls[0], + url: `https://yigil.co.kr/detail/spot/${params.id}`, + }; + return createMetadata(data); + } else + return { + title: '장소 상세 페이지', + description: '장소 상세 설명', openGraph: { - images: [spotDetail.data.image_urls[0]], + images: ['/public/logo/og-logo.png'], }, }; - } } else { const courseDetail = await getCourseDetail(params.id); if (courseDetail.status === 'succeed') { - return { + const data = { title: courseDetail.data.title, description: courseDetail.data.description, + image: courseDetail.data.map_static_image_url, + url: `https://yigil.co.kr/detail/course/${params.id}`, + }; + return createMetadata(data); + } else + return { + title: '코스 상세 페이지', + description: '코스 상세 설명', openGraph: { - images: [courseDetail.data.map_static_image_url], + images: ['/public/logo/favicon.svg'], }, }; - } } } @@ -52,7 +68,7 @@ export default async function SpotDetailPage({ if (params.travel === 'spot') { const spotDetail = await getSpotDetail(params.id); - if (!spotDetail.success) + if (spotDetail.status === 'failed') return (
장소 상세 정보를 불러오는데 실패했습니다.
다시 시도해주세요. diff --git a/frontend/src/app/(with-header)/place/[id]/page.tsx b/frontend/src/app/(with-header)/place/[id]/page.tsx index 90ea90335..ddeddab97 100644 --- a/frontend/src/app/(with-header)/place/[id]/page.tsx +++ b/frontend/src/app/(with-header)/place/[id]/page.tsx @@ -1,5 +1,7 @@ import PlaceDetailWithMySpot from '@/app/_components/place/detail/PlaceDetailWithMySpot'; + + export default async function PlaceDetailPage({ params, }: { diff --git a/frontend/src/app/(without-header)/login/page.tsx b/frontend/src/app/(without-header)/login/page.tsx index 7656acbf4..caab35977 100644 --- a/frontend/src/app/(without-header)/login/page.tsx +++ b/frontend/src/app/(without-header)/login/page.tsx @@ -11,6 +11,8 @@ import GoogleLoginButton from '@/app/_components/ui/button/GoogleLoginButton'; import NaverLoginButton from '@/app/_components/ui/button/NaverLoginButton'; import { googleOAuthEndPoint } from '@/app/endpoints/api/auth/callback/google/constants'; + + export default async function LoginPage() { const { KAKAO_ID, GOOGLE_CLIENT_ID, NAVER_SEARCH_ID } = process.env; diff --git a/frontend/src/app/_components/mypage/hooks/myPageActions.ts b/frontend/src/app/_components/mypage/hooks/myPageActions.ts index cdac82a91..e724216b9 100644 --- a/frontend/src/app/_components/mypage/hooks/myPageActions.ts +++ b/frontend/src/app/_components/mypage/hooks/myPageActions.ts @@ -139,7 +139,7 @@ export const getSpotDetail = async (spotId: number) => { }, }); const result = await res.json(); - const parsedSpotDetail = mypageSpotDetailSchema.safeParse(result); + const parsedSpotDetail = parseResult(mypageSpotDetailSchema, result); return parsedSpotDetail; }; diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index 5403545c9..03b00f800 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -21,6 +21,20 @@ export const metadata: Metadata = { }, description: '지도 기반 장소 기록·공유 서비스', + openGraph: { + title: '이길로그 홈페이지', + description: '지도 기반 장소 기록·공유 서비스', + images: ['/public/logo/og-logo.png'], + type: 'website', + siteName: '이길로그', + url: 'https://yigil.co.kr', + locale: 'ko-KR', + }, + twitter: { + title: '이길로그 홈페이지', + description: '지도 기반 장소 기록·공유 서비스', + images: ['/public/logo/og-logo.png'], + }, }; export default function RootLayout({ children }: { children: ReactNode }) { diff --git a/frontend/src/utils.ts b/frontend/src/utils.ts index 0fc6d9098..e9daf15e3 100644 --- a/frontend/src/utils.ts +++ b/frontend/src/utils.ts @@ -97,3 +97,33 @@ export function parseResult( return { status: 'succeed', data: result.data }; } +export async function createMetadata(data: { + title: string; + description: string; + image: string; + url: string; +}) { + const { title, description, image, url } = data; + return { + title: title, + description: description, + openGraph: { + siteName: '이길로그', + url: url, + locale: 'ko-KR', + images: { + url: image, + alt: title, + }, + type: 'website', + }, + twitter: { + title: title, + description: description, + images: { + url: image, + alt: `${title}-이미지`, + }, + }, + }; +} From 5e4bc22cec381b62d6d5246fd1cb0f4b1a4f75d2 Mon Sep 17 00:00:00 2001 From: davidktlee Date: Mon, 1 Apr 2024 18:48:12 +0900 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20og=20image=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx | 4 ++-- frontend/src/app/layout.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx b/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx index 43f91c517..c7f6767a5 100644 --- a/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx +++ b/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx @@ -32,7 +32,7 @@ export async function generateMetadata({ title: '장소 상세 페이지', description: '장소 상세 설명', openGraph: { - images: ['/public/logo/og-logo.png'], + images: ['/logo/og-logo.png'], }, }; } else { @@ -50,7 +50,7 @@ export async function generateMetadata({ title: '코스 상세 페이지', description: '코스 상세 설명', openGraph: { - images: ['/public/logo/favicon.svg'], + images: ['/logo/favicon.svg'], }, }; } diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index 03b00f800..0b26b017b 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -24,7 +24,7 @@ export const metadata: Metadata = { openGraph: { title: '이길로그 홈페이지', description: '지도 기반 장소 기록·공유 서비스', - images: ['/public/logo/og-logo.png'], + images: ['/logo/og-logo.png'], type: 'website', siteName: '이길로그', url: 'https://yigil.co.kr', @@ -33,7 +33,7 @@ export const metadata: Metadata = { twitter: { title: '이길로그 홈페이지', description: '지도 기반 장소 기록·공유 서비스', - images: ['/public/logo/og-logo.png'], + images: ['/logo/og-logo.png'], }, }; From c150a5d3b1e638dd3d09ed8a53121a3239a6e993 Mon Sep 17 00:00:00 2001 From: davidktlee Date: Mon, 1 Apr 2024 23:31:21 +0900 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20og,=20twitter=20=EB=B0=8F=20?= =?UTF-8?q?=EB=A9=94=ED=83=80=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/(with-header)/(home)/nearby/page.tsx | 14 ++++++++++++ .../(home)/places/popular/page.tsx | 14 ++++++++++++ .../(home)/places/recommended/page.tsx | 14 ++++++++++++ .../(home)/places/regions/[id]/page.tsx | 14 ++++++++++++ .../app/(with-header)/(home)/search/page.tsx | 6 +++++ .../detail/[travel]/[id]/page.tsx | 22 +++++++++++++++++-- .../src/app/(with-header)/place/[id]/page.tsx | 14 ++++++++++++ .../src/app/(without-header)/login/page.tsx | 14 +++++++++++- frontend/src/app/layout.tsx | 8 +++---- frontend/src/utils.ts | 5 +---- 10 files changed, 113 insertions(+), 12 deletions(-) diff --git a/frontend/src/app/(with-header)/(home)/nearby/page.tsx b/frontend/src/app/(with-header)/(home)/nearby/page.tsx index be84ec8a8..cb9245552 100644 --- a/frontend/src/app/(with-header)/(home)/nearby/page.tsx +++ b/frontend/src/app/(with-header)/(home)/nearby/page.tsx @@ -3,8 +3,22 @@ import MapComponent from '@/app/_components/naver-map/MapComponent'; import ViewTravelMap from '@/app/_components/near/ViewTravelMap'; import { getMySpotIds } from '@/app/_components/near/hooks/nearActions'; import { myInfoSchema } from '@/types/response'; +import { Metadata } from 'next'; import React from 'react'; +export const metadata: Metadata = { + title: '장소/코스 검색', + description: `원하는 장소/코스를 검색해보세요.`, + openGraph: { + title: '장소/코스 검색', + description: `원하는 장소/코스를 검색해보세요.`, + }, + twitter: { + title: '장소/코스 검색', + description: `원하는 장소/코스를 검색해보세요.`, + }, +}; + export default async function NearbyPage() { const res = await authenticateUser(); const user = myInfoSchema.safeParse(res); diff --git a/frontend/src/app/(with-header)/(home)/places/popular/page.tsx b/frontend/src/app/(with-header)/(home)/places/popular/page.tsx index aae731189..eccde86f4 100644 --- a/frontend/src/app/(with-header)/(home)/places/popular/page.tsx +++ b/frontend/src/app/(with-header)/(home)/places/popular/page.tsx @@ -5,6 +5,20 @@ import { myInfoSchema } from '@/types/response'; import { Place } from '@/app/_components/place/places'; import { getPlaces } from '@/app/_components/place/places/action'; +import { Metadata } from 'next'; + +export const metadata: Metadata = { + title: '인기 장소/코스', + description: `현재 인기있는 장소/코스를 만나보세요.`, + openGraph: { + title: '인기 장소/코스', + description: `현재 인기있는 장소/코스를 만나보세요.`, + }, + twitter: { + title: '인기 장소/코스', + description: `현재 인기있는 장소/코스를 만나보세요.`, + }, +}; export default async function PopularPlacesPage() { const memberJson = await authenticateUser(); diff --git a/frontend/src/app/(with-header)/(home)/places/recommended/page.tsx b/frontend/src/app/(with-header)/(home)/places/recommended/page.tsx index 8b2b021d3..bd93f2a9e 100644 --- a/frontend/src/app/(with-header)/(home)/places/recommended/page.tsx +++ b/frontend/src/app/(with-header)/(home)/places/recommended/page.tsx @@ -3,6 +3,20 @@ import { myInfoSchema } from '@/types/response'; import { Place } from '@/app/_components/place/places'; import { getPlaces } from '@/app/_components/place/places/action'; +import { Metadata } from 'next'; + +export const metadata: Metadata = { + title: '맞춤 추천', + description: `개인별 맞춤 추천 지역의 장소/코스를 만나보세요.`, + openGraph: { + title: '맞춤 추천', + description: `개인별 맞춤 추천 지역의 장소/코스를 만나보세요.`, + }, + twitter: { + title: '맞춤 추천', + description: `개인별 맞춤 추천 지역의 장소/코스를 만나보세요.`, + }, +}; export default async function RecommendedPlacesPage() { const memberJson = await authenticateUser(); diff --git a/frontend/src/app/(with-header)/(home)/places/regions/[id]/page.tsx b/frontend/src/app/(with-header)/(home)/places/regions/[id]/page.tsx index 9ae4220ad..09d5e5de2 100644 --- a/frontend/src/app/(with-header)/(home)/places/regions/[id]/page.tsx +++ b/frontend/src/app/(with-header)/(home)/places/regions/[id]/page.tsx @@ -7,6 +7,20 @@ import { getInterestedRegions, getRegionPlaces } from '../../../action'; import DummyPlace from '@/app/_components/place/dummy/DummyPlace'; import { RegionPlaces } from '@/app/_components/place/places'; +import { Metadata } from 'next'; + +export const metadata: Metadata = { + title: '관심 지역', + description: `관심 지역을 설정하고 관심 지역의 장소/코스를 만나보세요.`, + openGraph: { + title: '관심 지역', + description: `관심 지역을 설정하고 관심 지역의 장소/코스를 만나보세요.`, + }, + twitter: { + title: '관심 지역', + description: `관심 지역을 설정하고 관심 지역의 장소/코스를 만나보세요.`, + }, +}; export default async function RegionsPlacePage({ params, diff --git a/frontend/src/app/(with-header)/(home)/search/page.tsx b/frontend/src/app/(with-header)/(home)/search/page.tsx index 5e3192985..40c7aef9f 100644 --- a/frontend/src/app/(with-header)/(home)/search/page.tsx +++ b/frontend/src/app/(with-header)/(home)/search/page.tsx @@ -6,6 +6,12 @@ import { myInfoSchema } from '@/types/response'; import type { TMemberStatus } from '@/context/MemberContext'; import BackendSearchBar from '@/app/_components/place/BackendSearchBar'; import TravelSearchResult from '@/app/_components/search/TravelSearchResult'; +import { Metadata } from 'next'; + +export const metadata: Metadata = { + title: '이길로그 검색 페이지', + description: '원하는 장소/코스를 검색해보세요.', +}; export default async function SearchPage({ searchParams, diff --git a/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx b/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx index c7f6767a5..1039795cc 100644 --- a/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx +++ b/frontend/src/app/(with-header)/detail/[travel]/[id]/page.tsx @@ -32,7 +32,16 @@ export async function generateMetadata({ title: '장소 상세 페이지', description: '장소 상세 설명', openGraph: { - images: ['/logo/og-logo.png'], + images: { + url: '/logo/og-logo.png', + alt: '이길로그 로고', + }, + }, + twitter: { + images: { + url: '/logo/og-logo.png', + alt: '이길로그 로고', + }, }, }; } else { @@ -50,7 +59,16 @@ export async function generateMetadata({ title: '코스 상세 페이지', description: '코스 상세 설명', openGraph: { - images: ['/logo/favicon.svg'], + images: { + url: '/logo/og-logo.png', + alt: '이길로그 로고', + }, + }, + twitter: { + images: { + url: '/logo/og-logo.png', + alt: '이길로그 로고', + }, }, }; } diff --git a/frontend/src/app/(with-header)/place/[id]/page.tsx b/frontend/src/app/(with-header)/place/[id]/page.tsx index ddeddab97..acb980470 100644 --- a/frontend/src/app/(with-header)/place/[id]/page.tsx +++ b/frontend/src/app/(with-header)/place/[id]/page.tsx @@ -1,6 +1,20 @@ import PlaceDetailWithMySpot from '@/app/_components/place/detail/PlaceDetailWithMySpot'; +import { getPlaceDetail } from '@/app/_components/place/detail/action'; +import { createMetadata } from '@/utils'; +export async function generateMetadata({ params }: { params: { id: number } }) { + const detailResult = await getPlaceDetail(params.id); + if (detailResult.success) { + const data = { + title: detailResult.data.place_name, + description: detailResult.data.address, + image: detailResult.data.thumbnail_image_url, + url: `https://yigil.co.kr/place/${params.id}`, + }; + return createMetadata(data); + } +} export default async function PlaceDetailPage({ params, diff --git a/frontend/src/app/(without-header)/login/page.tsx b/frontend/src/app/(without-header)/login/page.tsx index caab35977..b58494e68 100644 --- a/frontend/src/app/(without-header)/login/page.tsx +++ b/frontend/src/app/(without-header)/login/page.tsx @@ -10,8 +10,20 @@ import { naverOAuthEndPoint } from '@/app/endpoints/api/auth/callback/naver/cons import GoogleLoginButton from '@/app/_components/ui/button/GoogleLoginButton'; import NaverLoginButton from '@/app/_components/ui/button/NaverLoginButton'; import { googleOAuthEndPoint } from '@/app/endpoints/api/auth/callback/google/constants'; +import { Metadata } from 'next'; - +export const metadata: Metadata = { + title: '로그인', + description: `로그인 후 이길로그의 여러 기능을 만나보세요`, + openGraph: { + title: '로그인', + description: `로그인 후 이길로그의 여러 기능을 만나보세요`, + }, + twitter: { + title: '로그인', + description: `로그인 후 이길로그의 여러 기능을 만나보세요`, + }, +}; export default async function LoginPage() { const { KAKAO_ID, GOOGLE_CLIENT_ID, NAVER_SEARCH_ID } = process.env; diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index 0b26b017b..e613e0534 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -14,26 +14,24 @@ const Pretendard = localFont({ }); export const metadata: Metadata = { + metadataBase: new URL('https://yigil.co.kr'), title: '이길로그', - icons: { icon: [{ url: '/logo/favicon.svg', href: '/logo/favicon.svg' }], }, - description: '지도 기반 장소 기록·공유 서비스', openGraph: { title: '이길로그 홈페이지', description: '지도 기반 장소 기록·공유 서비스', - images: ['/logo/og-logo.png'], + images: { url: '/logo/og-logo.png', alt: '이길로그 로고 이미지' }, type: 'website', siteName: '이길로그', - url: 'https://yigil.co.kr', locale: 'ko-KR', }, twitter: { title: '이길로그 홈페이지', description: '지도 기반 장소 기록·공유 서비스', - images: ['/logo/og-logo.png'], + images: { url: '/logo/og-logo.png', alt: '이길로그 로고 이미지' }, }, }; diff --git a/frontend/src/utils.ts b/frontend/src/utils.ts index e9daf15e3..88dfd6f29 100644 --- a/frontend/src/utils.ts +++ b/frontend/src/utils.ts @@ -108,14 +108,11 @@ export async function createMetadata(data: { title: title, description: description, openGraph: { - siteName: '이길로그', url: url, - locale: 'ko-KR', images: { url: image, - alt: title, + alt: `${title}-이미지`, }, - type: 'website', }, twitter: { title: title,