React(CSR)에서 SEO, metadata 태그

2026. 7. 23. 17:38공부 공간

이 내용을 찾아보게 된 계기

포트폴리오 아카이빙 용 웹사이트를 재구성하던 중, 해당 사이트를 본 친구가 SEO, metadata 태그를 달아보는게 어떻겠냐는 추천이 있었다.

다음날 해보겠다-! 해놓고 오늘 드디어 정보를 찾아보는데, 내 사이트(React)에서는 기본으로 동작하지 않는다는 것을 알게되어 방법을 찾기 시작한 것이 계기기 되었다. 그러다 생각보다 재밌어서... 이것저것 다 찾아보게 되었다는 것


알아본 내용

 

1. 메타데이터 / SEO 설정이란?

: 웹페이지 <head> 태그 안에 포함되는 정보로, 검색엔진 수집 및 소셜 미디어 링크 공유 시 보여줄 정보를 정의하는 것.

  • 기본 SEO 태그: <title>, <meta name="description">, canonical URL 등 (검색 결과 노출용)
  • Open Graph(OG) / Twitter Cards: <meta property="og:image"> 등 (카카오톡, 트위터, 슬랙 공유 시 썸네일/제목/설명 카드 생성용)
이런게 있구나 알려주서 고맙띠 가오리 친구야 🥹

그런데!

 

Next.js 기반이라고 적혀있는 내용을 문득 본 것 같아 React vite 기반 사이트에서도 동작하긴 하는건가...? 라는 의문이 생겨 더 정보를 찾아보았다.

 

 ➤ 검색 결과: React에서는 기본 동작으로 인식을하지 못하고, 라이브러리를 다운받아야한다 함. (react-helmet-async)

 

그런데 왜 인식을 못하는거지...? 웹 동작 방식이 next랑 다른가? 검색엔진은 어떻게 작동하기에...?


2. 크롤러(Bot)는 어떻게 작동할까?

검색엔진 크롤러나 소셜 미디어(카카오톡 등)의 수집 봇은 링크를 방문할 때 다음과 같이 동작한다.

  1. 해당 URL로 HTTP 요청을 보낸다.
  2. 서버가 응답으로 준 초기 HTML을 받는다.
  3. 자바스크립트를 실행하기 전에 HTML 상단의 <head> 태그를 읽어 썸네일과 제목 정보를 수집한다.

크롤러는 브라우저처럼 자바스크립트가 완전히 실행될 때까지 기다려주지 않거나, 봇 자체가 JS 실행 엔진을 갖고 있지 않다는 게 핵심인듯


3. 웹 렌더링 방식

랜더링 방식 HTML 생성 위치 & 시점  SEO / OG 태그 작동 여부
CSR (일반 React) 브라우저 / 접속 후 JS 실행 시 초기 HTML이 비어있어 크롤러 수집 어려움
SSR (Next.js 등) 서버 / 매 요청 마다 즉시 생성 완성된 HTML이 내려오므로 완벽 지원
SSG (Static Site) 빌드 서버 / 배포(빌드) 시 1회 생성 미리 만든 HTML이 제공되므로 완벽 지원

 

➤ React는 CSR 방식으로 SEO / OG 태그가 dafault로 작동하지 않는다.


4-1. 그래서 방법은?

react-helmet-async 라이브러리 사용!

: React 컴포넌트 내부에서 DOM을 직접 조작해 브라우저의 <head> 태그를 동적으로 바꿔주는 라이브러리. 

 

메타 태그 적용! ✓

그런데...!

OG(Open Graph)의 경우!

해당 동작은 어디까지나 클라이언트에서 JS가 실행된 후에 일어나므로, 서버가 전달하는 초기 HTML은 여전히 비어있으므로 카카오톡/슬랙 봇처럼 JS를 실행하지 않는 크롤러는 react-helmet-async로 바꾼 메타 태그를 읽지 못하고 기본/빈 썸네일만 노출된단다.

...네?

 

4-2. 그래서 방법은? (OG)

하드코딩 or 봇 감지 & 서버, CDN 우회 처리(동적 썸네일) or 빌드 타임 프리렌더링(Prerender)

... 일단 이 내용 정리를 마무리하고 코드 구현을 하러 갈 예정이니 자세한 내용은 구현을 하면서 찾아보기로. 

하지만 아마 하드코딩 할 듯? 무거운 중요 기능은 아니니...


5. 정리하자면

React는 빈 HTML + JS를 가져온 후, 사용자(클라이언트)가 브라우저를 접속하고나서 JS를 실행하는 방식(CSR)의 렌더링 방식을 가진다. 

따라서 React에서는 <head> 태그 내부에 정보를 입력하여 사용하는 SEO, OG가 기본적으로 동작하지 않는다.

해당 기능을 사용하기 위해서는 react-helmet-async 라이브러리를 사용하여야하며 이 경우 메타데이터만 적용된다. OG는 여전히 동작하지 않고, 다른 방법을 사용해야 한다...







그리고 발견한 이슈(2)

react-helmet-async를 무작정 사용하려다가, 아까의 같은 친구가 그거 그냥 index.html에 박아넣으면 된다...!라고 전해주었다.

 

듣고보니, 어라... 맞는 말이잖아...? 싶어 왜 react-helmet-async를 claude가 추천해준건지 고민하며 다시 코드를 들여다보니, '/'와 '/commission'으로 분리해 따로 빼둔 엔드포인트가 문제였던 것 같다. 별로 중요하지는 않은 취미용 아카이브인데(딱히 검색 엔진에 등록할 생각은 없는) 이걸 동적으로 메타 정보를 변경해야할 곳으로 읽었다보다. 🥲

 

역시 ai 무작정 믿는게 아니다

 

그래서 결론은 그냥 index.html에 넣기로...

 

이후 해결해야 할 것은 이미지 렌더링이 매우 느려 한참 뒤에 이미지가 보이는 문제다

 

 

https://hamon1.github.io/PortfolioWebSite/