-
[React / 에러 핸들링] react-helmet, react-snap 안될때 해결 방법React 2022. 3. 4. 23:54
사이드 프로젝트를 진행하면서 링크 공유 기능을 구현할 일이 생겼습니다.
이때 OG태그를 사용하면서 생긴 에러를 써보려 합니다.
메타데이터
메타데이터는 데이터를 설명하는 데이터입니다.
그중에서도 OG 태그라는 것이 있는데 Facebook이 웹 사이트에 더 풍부한 메타데이터를 제공하기 위해 발명한 메타데이터 프로토콜입니다.
메타데이터들을 사용한다면 검색엔진에게 더 많은 데이터를 제공하므로 좋습니다.
뿐만 아니라 og태그를 사용하게 된다면 링크를 공유했을 때 사용자에게 더 좋은 정보를 보여줄 수 있습니다.
CRA와 meta data의 문제
프로젝트의 기술 스택은 cra였습니다.
해야 하는 일은 og태그를 사용하여 동적으로 url에 해당하는 이미지 및 사진을 보여주어야 합니다.
하지만 csr은 index.html이 하나입니다. 때문에 동적으로 meta 데이터를 생성할 수 없습니다.
ssr을 하게 된다면 정적인 페이지를 서버 사이드에서 만들어진 상태이기 때문에 쉽게 meta 데이터들을 적용할 수 있습니다.
react-helmet 적용하기
react-helmet을 적용하게 된다면 동적으로 meta데이터를 적용할 수 있습니다.
import React from "react"; import {Helmet} from "react-helmet"; class Application extends React.Component { render () { return ( <div className="application"> <Helmet> <meta charSet="utf-8" /> <title>My Title</title> <link rel="canonical" href="http://mysite.com/example" /> </Helmet> ... </div> ); } };
다음과 같은 방식으로 아주 편하게 사용할 수 있습니다.
사실 helmet만을 사용해서 og태그를 설정하여도 원하는 결과는 나오게 됩니다.
하지만 이왕 Meta data를 적용한 김에 seo까지 신경 써보기로 마음먹게 되었습니다.
react-snap 적용하기
여전히 빌드를 하게 되면 html파일이 index.html 하나만 존재하는 것을 확인할 수 있습니다.
즉, helmet으로 meta 데이터를 적용한다고 하더라도 server side에서는 하나의 html만이 존재한다는 뜻입니다.
따라서 js를 읽기 힘들어하는 seo는 metadata를 읽을 수 없습니다. 이러한 것 들을 해결해 주는 것이 react-snap입니다.
react-snap의 문서를 보게 된다면 Pre-renders a web app into static HTML라는 말을 볼 수 있습니다. 사용하는 방식은 문서를 보게 된다면 자세히 나와 있습니다.
에러 상황
하지만 여기서 문제가 나타나게 됩니다.
아무리 하여도 하나의 index.html파일만 나타나게 되는 것입니다.
저의 폴더 구조는 App.tsx에서 react-router로 라우팅 처리를 선언하는 방식으로 사용하였습니다.
구글링을 계속해보았지만, 다 공식문서에 나와있는 방식대로 설명한 글이었습니다.
따라서 어쩔 수 없이 react-snap을 직접 까 보게? 되었습니다.
react-snap의 코드를 보면
if (!options.publicPath.startsWith("/")) { options.publicPath = `/${options.publicPath}`; } options.publicPath = options.publicPath.replace(/\\/$/, ""); options.include = options.include.map( include => options.publicPath + include ); return options;
이런 부분을 볼 수 있습니다.
options의 include 프로퍼티를 돌면서 publicPath와 include url을 더해주는 부분입니다.
옵션은 reactSnap이라는 프로퍼티를 package.json에 정의함으로써 수정할 수 있는데 이는 공식문서에 나와 있습니다.
따라서 저는 제가 prerender 하기 위해 필요한 url을 package.json에 명시해 주었습니다.
"reactSnap": { "include":["/","/details"] }
react-snap을 사용하면서 빌드 시 html 파일이 여러 개 생기지 않으셨던 분들은
react-snap의 공식문서에 나와있는 대로 설정한 다음 package.json에 별도의 url을 설정하신다면 잘 해결됩니다.
어떤 경우 이런 문제가 생기는지 더 테스트해본 결과 app.tsx에서 link태그 또는 데이터가 있는 상태에서 react-router로 outlet 설정을 한 경우, app.tsx에서 있는 링크들은 여러 개의 html로 잘 빌드가 됩니다.
하지만 app.tsx에서 라우팅을 정의한 경우 다음과 같은 에러가 발생하는 것 같습니다.
참고 문서
https://developer.mozilla.org/ko/docs/Learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML
'React' 카테고리의 다른 글
Toast Editor toolbar 에러 (0) 2022.05.12 [React] React-router는 내부적으로 history api를 사용하는지 확인하기 (0) 2022.03.25 [React / 에러 핸들링] Modal컴포넌트 만들기 (0) 2022.02.08 [React / 에러 핸들링] useClickAway훅 만들기 (0) 2022.02.04 [React] dropdown(selectBox) 시멘틱하게 만들기 (1) 2022.01.24