-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
setting : SEO 를 위한 세팅 #215
Changes from 5 commits
4a89728
30c022c
7a66910
5a91284
aabb380
f3f7b1f
c495a8b
3f2d410
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
NEXT_PUBLIC_API_BASE_URL=https://fe-adv-project-together-dallaem.vercel.app/3-4 | ||
NEXT_PUBLIC_BASE_URL=https://soothe-with-me.vercel.app |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 메타데이터는 client 컴포넌트에서 선언할 수 없기 때문에, saved 페이지는 layout 파일을 따로 만들었습니다. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { Metadata } from 'next'; | ||
import { ReactNode } from 'react'; | ||
import { pageMetadata } from '@/utils/makeMetadata'; | ||
|
||
export const metadata: Metadata = pageMetadata('찜한 모임', '/saved'); | ||
|
||
const Layout = ({ | ||
children, | ||
}: Readonly<{ | ||
children: ReactNode; | ||
}>) => { | ||
return <>{children}</>; | ||
}; | ||
|
||
export default Layout; |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
User-agent: * | ||
Disallow: /mypage/ | ||
Allow: / | ||
|
||
Sitemap: https://soothe-with-me.vercel.app/sitemap |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. https://nextjs.org/docs/app/api-reference/file-conventions/metadata/sitemap 사이트맵은 xml로 작성되어야 하나, 넥스트에서는 app/sitemap.ts 파일로 프로그래밍식으로 생성할 수 있습니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 최고에요👍👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { MetadataRoute } from 'next'; | ||
|
||
const BASE_URL = `${process.env.NEXT_PUBLIC_BASE_URL}`; | ||
|
||
export default function sitemap(): MetadataRoute.Sitemap { | ||
return [ | ||
{ | ||
url: BASE_URL, | ||
lastModified: new Date(), | ||
changeFrequency: 'yearly', | ||
priority: 0.5, | ||
}, | ||
{ | ||
url: `${BASE_URL}/gatherings`, | ||
lastModified: new Date(), | ||
changeFrequency: 'daily', | ||
priority: 1, | ||
}, | ||
{ | ||
url: `${BASE_URL}/saved`, | ||
lastModified: new Date(), | ||
changeFrequency: 'daily', | ||
priority: 0.8, | ||
}, | ||
{ | ||
url: `${BASE_URL}/reviews`, | ||
lastModified: new Date(), | ||
changeFrequency: 'daily', | ||
priority: 0.8, | ||
}, | ||
{ | ||
url: `${BASE_URL}/signup`, | ||
lastModified: new Date(), | ||
changeFrequency: 'yearly', | ||
priority: 0.5, | ||
}, | ||
{ | ||
url: `${BASE_URL}/signin`, | ||
lastModified: new Date(), | ||
changeFrequency: 'yearly', | ||
priority: 0.5, | ||
}, | ||
{ | ||
url: `${BASE_URL}/mypage`, | ||
lastModified: new Date(), | ||
changeFrequency: 'daily', | ||
priority: 0.7, | ||
}, | ||
{ | ||
url: `${BASE_URL}/mypage/review/writable`, | ||
lastModified: new Date(), | ||
changeFrequency: 'daily', | ||
priority: 0.7, | ||
}, | ||
{ | ||
url: `${BASE_URL}/mypage/review/written`, | ||
lastModified: new Date(), | ||
changeFrequency: 'daily', | ||
priority: 0.7, | ||
}, | ||
{ | ||
url: `${BASE_URL}/mypage/created`, | ||
lastModified: new Date(), | ||
changeFrequency: 'daily', | ||
priority: 0.7, | ||
}, | ||
]; | ||
} |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 페이지명을 파라미터로 받아 메타데이터를 리턴하는 유틸 함수 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이건 진짜 손민수할 코드네요 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 메타데이터를 이렇게 관리할 수 있다는 걸 처음 알았네요...! 많이 배워갑니다! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
const BASE_URL = `${process.env.NEXT_PUBLIC_BASE_URL}`; | ||
|
||
export const rootMetadata = { | ||
metadataBase: new URL(BASE_URL), | ||
title: { | ||
template: '%s | Soothe With Me', | ||
default: 'Soothe With Me', | ||
}, | ||
description: | ||
'바쁜 일상 속 휴식을 위한 다양한 모임을 탐색하고 참여하며, 직접 모임을 개설하고 리뷰를 생성할 수 있는 서비스입니다.', | ||
icons: { | ||
icon: '/icons/bye.svg', | ||
}, | ||
keywords: | ||
'같이달램, Soothe with me, 달램핏, 워케이션, 마인드풀니스, 오피스스트레칭, 모임, 휴식, 소통, 힐링, 취미, 취향, 소모임', | ||
robots: { | ||
index: true, | ||
follow: true, | ||
}, | ||
openGraph: { | ||
title: { | ||
template: '%s | Soothe With Me', | ||
default: 'Soothe With Me', | ||
}, | ||
description: | ||
'다양한 휴식 모임을 탐색하고 참여하며 직접 개설할 수 있는 서비스.', | ||
url: BASE_URL, | ||
siteName: 'Soothe With Me', | ||
type: 'website', | ||
locale: 'ko_KR', | ||
images: [ | ||
{ | ||
url: '/images/login-img.svg', | ||
width: 800, | ||
height: 600, | ||
alt: 'Soothe With Me', | ||
}, | ||
], | ||
}, | ||
twitter: { | ||
title: { | ||
template: '%s | Soothe With Me', | ||
default: 'Soothe With Me', | ||
}, | ||
description: | ||
'바쁜 일상 속 휴식을 위한 다양한 모임을 제공하는 Soothe With Me 서비스.', | ||
images: [ | ||
{ | ||
url: '/images/login-img.svg', | ||
width: 800, | ||
height: 600, | ||
alt: 'Soothe With Me', | ||
}, | ||
], | ||
}, | ||
alternates: { | ||
canonical: `${process.env.NEXT_PUBLIC_BASE_URL}/gatherings`, | ||
}, | ||
other: { | ||
'google-site-verification': '3TzGNrqEDpp12jYWOwKcH92cFxvYmfrz-0lspdNdTwo', | ||
}, | ||
}; | ||
|
||
import getGatheringInfo from '@/app/api/actions/gatherings/getGatheringInfo'; | ||
import { GatheringInfoType } from '@/types/data.type'; | ||
|
||
export const pageMetadata = (page: string, path: string) => { | ||
return { | ||
title: { | ||
template: '%s | Soothe With Me', | ||
default: page, | ||
}, | ||
description: `Soothe With Me ${page} 페이지입니다.`, | ||
openGraph: { | ||
title: page, | ||
description: `Soothe With Me | ${page} .`, | ||
url: `${BASE_URL}${path}`, | ||
}, | ||
twitter: { | ||
title: page, | ||
description: `Soothe With Me | ${page} .`, | ||
url: `${BASE_URL}${path}`, | ||
}, | ||
}; | ||
}; | ||
|
||
export const gatheringMetadata = async (id: number) => { | ||
const gatheringInfo: GatheringInfoType = await getGatheringInfo(id); | ||
|
||
const name = gatheringInfo.name || ''; | ||
const type = gatheringInfo.type; | ||
const img = gatheringInfo.image; | ||
|
||
return { | ||
title: name, | ||
description: `${type} : ${name}`, | ||
openGraph: { | ||
title: name, | ||
description: `${type} : ${name}`, | ||
url: `${BASE_URL}/gatherings/${id}`, | ||
images: [ | ||
{ | ||
url: img || '/images/login-img.svg', | ||
width: 800, | ||
height: 600, | ||
alt: `${name} 모임 이미지`, | ||
}, | ||
], | ||
}, | ||
twitter: { | ||
title: name, | ||
description: `${type} : ${name}`, | ||
url: `${BASE_URL}/gatherings/${id}`, | ||
images: [ | ||
{ | ||
url: img || '/images/login-img.svg', | ||
width: 800, | ||
height: 600, | ||
alt: `${name} 모임 이미지`, | ||
}, | ||
], | ||
}, | ||
}; | ||
}; | ||
Comment on lines
+87
to
+124
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 응용 미쳤네요! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
generateMetadata
는 동적으로 메타데이터를 생성하는 함수로,동적라우팅 시 파라미터 값을 받아 메타데이터 생성에 적용할 수 있습니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P4) (그냥 질문) 혹시 dynamic routes 가 적용된 페이지는 이런 식으로 페이지 내부에 직접 함수를 적용해줘야 하는 걸까요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dynamic routes 역시 기본적으로 layout 이나 page 파일에서 정적 메타데이터로 내보내기 할 수 있습니다.
다만 dynamic routes 의 세그먼트나 다른 파라미터 등을 이용해서 메타데이터를 동적으로 생성하고 싶을 때
generateMetadata
함수를 사용합니다. (dynamic routes가 아니어도 사용 가능)즉 정적 생성, 동적 생성은 모든 라우트 종류에 가능하며 필수 요소가 아닙니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오..... 상세한 답변 감사합니다!