일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- node.js(express) + ws(websocket) + react
- express로 채팅 기능 구현하기
- css module classNames
- app.listen
- next.js
- 코드잇 스프린트 FE 1기
- inferred type error
- CSS module 장점
- usemutation custom hook
- 이미지 업로드 과정
- 오블완
- useimperativehandle 사용할때
- 리액트 19 useref
- trigger additional callbacks
- 티스토리챌린지
- http.createserver
- useimperativehandle 사용법
- useref 타입
- express react
- type reference cannot be named error
- components as formulas
- 프리렌더링
- 리스티웨이브
- 특정 dom node만 노출시키고 싶을 때
- 리액트로 채팅 기능 구현하기
- 회고
- 스프린트 여정 마침
- React
- pure functions
- dynamic metadata
- Today
- Total
Life is connecting the dots .
SEO 향상을 위한 Metadata API 적용하기 본문
Next.js는 최적화(Optimizations)를 위해 기본적으로 제공되는 기능들이 있다.
공식문서를 참고하여 간략하게 소개하자면 먼저, 빌트인 컴포넌트를 사용하여 UI를 최적화하기 위해 복잡하게 구성해야 하는 요소들을 쉽게 만들어 줄 수 있다. Images, Link, Scripts와 같은 컴포넌트들이 이러한 역할을 한다.
다음으로 Metadata를 활용하여 웹사이트의 콘텐츠를 검색엔진에 더 잘 노출되도록 하고, 어떻게 보일 지를 커스텀하여 다양한 플랫폼에서 일관적인 사용자 경험을 줄 수 있는 방법이 있다. Next.js의 Meatadata API는 HTML의 <head> 요소를 수정할 수 있게 해 줌으로써 웹사이트 SEO를 향상시키기 위한 방법을 제공한다.
드림코딩 강의를 통해 Next.js(v13)과 React(v18)을 공부하며 만든 블로그에서 challenge를 하며 메타데이터를 적용하는 과정을 글로 작성하게 되었다.
메타데이터를 추가하는 방법에는 크게 두 가지가 있다.
1️⃣ Config-based Metadata
: layout.js 또는 page.js에 Metadata를 생성해 주는 방법으로 데이터가 '정적'이냐 '동적'이냐에 따라 두 가지로 나뉜다. 또한, 포인트는 Server Components에서만 지원된다는 점이다.
❒ Static Metadata : Metadata 객체를 생성하여 메타데이터를 정의하는 방법
❒ Dynamic Metadata : generateMetadata 함수를 사용
2️⃣ File-based Metadata : 특정 파일을 추가하여 메타데이터를 생성하는 방법
Static Metadata
- Next.js를 생성하면 src/app/layout.tsx 경로에 기본적으로 메타데이터(title, description)가 생성되어있다. 이 부분을 string 또는 template object를 사용하여 넣고 싶은 데이터를 정의할 수 있고, 메타데이터 Fields 옵션을 추가할 수 있다.
import type { Metadata } from "next";
...
export const metadata: Metadata = {
// Template Object
title: {
template: "%s | 소현의 블로그",
default: "소현의 블로그", // 대체 제목 (required)
},
description: "welcome to my secret blog! 👑",
authors: [{ name: "ParkSoHyun" }],
generator: "Next.js",
applicationName: "Blog",
referrer: "origin-when-cross-origin",
keywords: ["Next.js", "React", "JavaScript"],
};
이렇게 메타데이터를 정의해 주면 Next.js에서 HTML head태그 안에 <meta> 태그로 데이터를 생성해 준다.
앞서 Template Object로 정의한 title.template은 하위 경로의 페이지 제목이 있다면 그 제목을 접두사 또는 접미사를 더하여 템플릿 형태로 나타내는 역할을 한다. 반면에 제목이 정의되어 있지 않는 페이지는 title.default 값을 title로 보여준다.
블로그 내 About, Posts, Contact 페이지 각각에 서로 다른 옵션을 적용해 보았다.
✅ About 페이지 - 제목이 레이아웃에서 정의해 둔 템플릿 형태로 보여진다.
// app/about/page.tsx
import { Metadata } from "next";
export const metadata: Metadata = {
title: "About me",
};
// <head> output
<title>About me | 소현의 블로그</title>
✅ Posts 페이지 - title.absolute를 사용하면 상위 경로에서 정의된 탬플릿을 무시한다.
// app/posts/page.tsx
import { Metadata } from "next";
export const metadata: Metadata = {
title: {
absolute: "블로그 포스트",
},
};
// <head> output
<title>블로그 포스트</title>
✅ Contact 페이지 - 이번에는 아무런 메타데이터를 정의해 주지 않았다. 그러므로 title.default로 정의한 제목이 보여진다.
// app/contact/page.tsx
import { Metadata } from "next";
export const metadata: Metadata = {};
// <head> output
<title>소현의 블로그</title>
Dynamic metadata
그렇다면 동적으로 생성되는 데이터의 메타데이터는 어떻게 정의할 수 있을까? 바로 Next.js에서 제공하는 generateMetadata 함수를 사용하여 동적인 값을 불러와 메타데이터로 넣어줄 수 있다.
공식문서에서는 Fetch API로 불러온 데이터를 return값으로 넣어주는데 여기서는 getPostDetail 함수가 각 post에 해당하는 글을 찾아서 보여주는 로직이다. 이후 post 객체에 들어있는 title과 description 필드를 메타데이터로 반환한다.
// app/posts/[post]/page.tsx
import { Metadata } from "next";
...
interface Props {
params: {
post: string;
};
}
export async function generateMetadata({params: { post }}: Props): Promise<Metadata> {
const { title, description } = await getPostDetail(post);
return {
title,
description,
};
}
...
페이지를 동작시켜 보면 게시물을 클릭했을 때 제목과 내용이 각 글에 맞는 내용으로 동적으로 생성되는 것을 알 수 있다. 제목은 상위 컴포넌트 즉, layout.tsx에서 정의한 탬플릿 형태로 보여진다. 참고로 meta charset 태그와 viewport 태그는 정의하지 않아도 메타데이터에 추가되는 default 필드이다.
File-based Metadata
다음으로 메타데이터를 정의할 수 있는 방법으로 특정한 파일(special files)을 추가하는 방법이 있다. file-based metadata는 config-based metadata보다 높은 우선순위를 갖으며 config-based metadata를 재정의한다.
메타데이터에 이용할 수 있는 여러 가지 파일들이 있지만 파비콘과 오픈그래프를 사용해 보기로 했다.
❒ favicon★
파비콘에 해당하는 이미지를 app/favicon.ico 경로에 생성해서 넣어주면 Next.js에서 자동으로 해드 태그에 파비콘을 넣어준다.
<!-- <head> output -->
<link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="any">
❒ openGraph
다음으로 오픈그래프를 추가해 주기 위해 OG이미지를 먼저 생성해 주었다. OG는 2가지 방법으로 만들어 주었는데, 이미지 같은 경우에는 조금 더 사용하기 쉬운 File-based Metadata 방법을 적용하여 app/ 경로에 이미지와 이미지를 대체할 수 있는 정보(opengraph-image.alt.txt)도 같은 경로에 넣어주었다.
이렇게만 하면 이미지에 대한 부분만 OG로 생성되기 때문에 2번째 방법으로 layout.tsx에 추가로 넣고 싶은 OG데이터를 넣어주었다.
import type { Metadata } from "next";
...
export const metadata: Metadata = {
...
openGraph: {
title: "소현의 블로그",
description: "개발 관련 블로그",
url: "https://blog-project-psi-sand.vercel.app",
type: "website",
},
};
<!-- <head> output -->
<meta property="og:title" content="소현의 블로그">
<meta property="og:description" content="개발 관련 블로그">
<meta property="og:url" content="https://blog-project-psi-sand.vercel.app">
<meta property="og:image:type" content="image/png">
<meta content="683" property="og:image:width">
<meta content="449" property="og:image:height">
<meta content="http://localhost:3000/opengraph-image.png?071101f06404077d" property="og:image">
<meta content="website" property="og:type">
Metadata와 OG까지 적용함으로써 블로그 웹사이트에 향상된 SEO와 웹 공유성을 더해주었다. Next.js는 이와 관련된 모든 기능을 간편하게 제공해 주고, 이미지 크기 등을 자동적으로 최적화해 주기 때문에 Next.js를 사용하는 또 하나의 장점으로 생각되는 부분이다.
Behavior
마지막으로 메타데이터를 생성하는 데에 두 가지 방법이 있기 때문에 어떻게 동작하는지 순서에 유의해서 사용해야 한다. 먼저 언급한 file-based metadata는 config-based metadata보다 높은 우선순위를 갖는다는 점과 함께 Metadata는 다음과 같은 순서대로 적용된다.
✔️ Ordering
1️⃣ app/layout.tsx (Root Layout)
2️⃣ app/blog/layout.tsx (Nested Blog Layout)
3️⃣ app/blog/[slug]/page.tsx (Blog Page)
✔️ Merging
위의 순서대로 적용하면서 중복된 키가 있다면 순서대로 메타데이터를 대체한다. 즉, 하위 경로에서 제목이 변경된다면 그 제목으로 대체되고, 만약 OG데이터가 중복해서 있다면 해당 페이지는 나중에 정의된 메타데이터로 대체된다.
여기서 포인트는 Overwriting, 즉, 덮어씌워진다는 의미이다. 그래서 layout에서 적용한 OG를 blog페이지의 OG가 덮어씌운다면 기존 정의된 description 필드는 더 이상 나타나지 않는다.
// 공식문서 example
// app/layout.js
export const metadata = {
title: 'Acme',
openGraph: {
title: 'Acme',
description: 'Acme is a...',
},
}
// app/blog/page.js
export const metadata = {
title: 'Blog',
openGraph: {
title: 'Blog',
},
}
// Output:
// <title>Blog</title>
// <meta property="og:title" content="Blog" />
만약 중복된 필드를 덮어씌우되, 설정하지 않은 다른 필드를 그대로 공유하고 싶다면 별도 변수를 만들어서 상속하는 방법이 있다. 이 부분은 공식문서로 대체한다. Inheriting fields
배포가 완료된 이후 카톡으로 웹사이트 링크를 공유하면 OG로 설정한 정보가 나타나는 것을 확인할 수 있다.
'Programming > Next.js' 카테고리의 다른 글
Next.js 정의, 등장 배경 및 특징 (프리렌더링, SSR) (0) | 2024.11.08 |
---|---|
[프로젝트] 리스티웨이브 SEO 개선하기(Dynamic Metadata, Sitemap, Robots.txt) (+. 9월까지 변화) (0) | 2024.05.19 |
Next.js에서 CSS module, Styled-components 사용하기 (0) | 2023.12.02 |
Vercel로 Next.js 프로젝트 배포하기 (0) | 2023.07.04 |
Optimistic UI 적용하기 (feat. Update cache in Apollo Client) (0) | 2023.07.02 |