react app의 부분을 동적으로 관리할 수 있도록 도와주는 라이브러리이다.
react-helmet의 문제점을 해결하기 위해 만들어진 포크(fork) 버전이다.
react-helmet이 thread-safe하지 않은 react-side-effect에 의존하고 있어 서버 사이드 렌더링 환경에서 비동기 작업을 처리할 때 문제가 발생할 수 있다 .⇒ thread-safe를 지원하지 않기 때문
예를 들어, A 사용자가 페이지 1을 요청하고, B 사용자가 페이지 2를 요청한다고 가정해봅시다.
<head>
태그 정보가 섞여버릴 수 있습니다. 즉, A의 요청에 B의 페이지 정보가 들어가거나, 반대로 B의 페이지에 A의 정보가 들어가는 혼란스러운 상황이 발생할 수 있죠.이게 바로 thread-safe하지 않다는 말의 의미입니다. 동시에 여러 요청이 처리될 때, 서로의 데이터가 충돌하고 섞여버리는 문제가 발생할 수 있다는 뜻이죠.
[react-helmet의 package.json]
"dependencies": {
"object-assign": "^4.1.1",
"prop-types": "^15.7.2",
"react-fast-compare": "^3.1.1",
"react-side-effect": "^2.1.0"
},
위의 코드를 보면 react-side-effect가 디펜던시로 추가 되어 있음을 확인할 수 있었다.
그럼 react-helmet-async의 package.json에는있을까? 없다.
"dependencies": {
"invariant": "^2.2.4",
"react-fast-compare": "^3.2.2",
"shallowequal": "^1.1.0"
},
실제로 react-helmet은 마지막 업데이트가 2024.09 기준 4년전이 마지막이다.
: 하나의 index.html을 두고 있기 때문에 페이지 마다 페이지를 설명하는 메타태그를 설정하기 어렵다.
위와 같은 이유로 브라우저 크롤러가 페이지를 크롤링 할 때 모든 페이지의 정보를 가져올 수 없어 SEO에는 좋지 않다.
npm i react-helmet-async
function App() {
return (
<ThemeProvider theme={theme}>
...
<HelmetProvider>
<Router />
</HelmetProvider>
...
</ThemeProvider>
);
}
import React from 'react';
import { Helmet } from 'react-helmet-async';
const HomePage = () => {
return (
<div>
<Helmet>
<title>Home - My Website</title>
<meta name="description" content="Welcome to the home page of My Website" />
<meta property="og:title" content="Home - My Website" />
<meta property="og:description" content="This is the home page of My Website" />
<meta property="og:url" content="https://www.mywebsite.com/" />
<meta property="og:type" content="website" />
</Helmet>
<h1>Home Page</h1>
<p>Welcome to the home page!</p>
</div>
);
};
export default HomePage;
(1) <meta name="description">
(2) <meta name="viewport">
(1) Open Graph Tags (OG 태그)
<meta property="og:title" content="웹 페이지 제목">
<meta property="og:description" content="웹 페이지에 대한 설명">
<meta property="og:image" content="https://www.example.com/image.jpg">
<meta property="og:url" content="https://www.example.com/">
og:title
: 공유할 때 보이는 제목.og:description
: 공유할 때 보이는 설명.og:image
: 공유할 때 표시되는 이미지 URL.og:url
: 해당 콘텐츠의 URL.og:type
: 콘텐츠의 유형을 정의 (예: article
, website
).import { Helmet } from 'react-helmet-async';
interface Props {
title: string;
description: string;
keywords: string;
imgsrc?: string;
url: string;
}
function MetaTag(Meta: Props) {
const { title, description, keywords, imgsrc, url } = Meta;
return (
<Helmet>
<title>{title}</title>
<meta name='description' content={description} />
<meta name='keywords' content={keywords} />
<meta property='og:type' content='website' />
<meta property='og:title' content={title} />
<meta property='og:site_name' content={title} />
<meta property='og:description' content={description} />
<meta property='og:image' content={imgsrc} />
<meta property='og:url' content={url} />
<link rel='canonical' href={url} />
</Helmet>
);
}
export default MetaTag;
[가지고 와서 재사용]
<MetaTag
title='리크루트 - 전통주와 함께하는 새로운 경험'
description='리크루트 메인 페이지에서 전통주와 관련된 다양한 정보를 만나보세요.'
keywords='리크루트, 전통주, 메인 페이지'
imgsrc={IMAGES.banner}
url='https://www.licruit.site'
/>
[index.html]
[main.tsx] ⇒ home