트러블슈팅 & 알게된 것

Client-side rendering(CSR) 웹사이트 동적 OG(OpenGraph) 메타태그 적용을 위한 방안

2dubbing 2024. 8. 5. 21:54

당시 재직하던 회사에서 운영 중인 웹 프로젝트는 Create-React-App(이하 CRA) 으로 구조를 잡아 개발하고 있었다.
 
사용자가 웹사이트에 들어와 컨텐츠를 보고 기능을 사용하는데 문제는 없었으나, 웹사이트에 들어오기 전 단계에서는 문제가 있었다.
 
Client-side rendering(CSR) 이더라도 정적 데이터를 사용한다면 문제가 없으나, 상품 상세보기 페이지와 같이 상품에 대한 상세정보를 서버에서 제공 받아야 하는 경우에는 검색엔진 봇(Bot)에게 데이터를 제공해 줄 수가 없다.  

 
이를 해결하려면 검색엔진 봇이 웹서버에 접근했을 때, 서버에서 렌더링 하는 SSR(Server side rendering) 혹은 Build 시점에 외부데이터를 사용해 정적페이지를 렌더링하는 Next.js 의 SSG(Static site generation) 방식을 사용해야 한다.
 
하지만 이를 해결하고자 CRA 에서 Next.js 로 프로젝트를 마이그레이션 하기에는 시간과 개발자 리소스 측면에서 효율적이지 못하다는 생각이 들었다.
 
해결방법을 찾기위해 여러회사의 기술블로그와 인터넷검색을 하던 중, Google 개발자 블로그에서 'Rendertron 을 사용한 동적렌더링' 포스팅을 찾을 수 있었고 여기서 아이디어(?) 를 얻을 수 있었다.
https://developers.google.com/search/blog/2019/01/dynamic-rendering-with-rendertron?hl=ko
 

주요 내용은 '서버에 Static HTML 생성을 위한 Rendertron App 을 추가하고, Bot 요청으로 들어오는 경우에 Rendertron App 으로 라우팅 시켜 Static HTML 을 반환' 이다.

 

Rendertron 에는 headless chromium 을 사용했으나, 좀 더 찾다보니 puppeteer 자체도 chromium 기반이니 사용가능 했다.

 

당시에 글을 읽자마다 바로 시도했었는데, 특별한 로직이 필요치 않아 빠르게 로컬에서 테스트 해 볼 수 있었다.

다만 이를 AWS Lambda 를 사용해 배포하려 했으나, puppeteer 용량이 커 Lambda 에 띄울 수 없는 문제가 있었다.

그래서 EC2 를 사용해 서버를 띄워서 사용했다. 

 

 

당시 구현했던 코드를 백업해두지 않았으나, 간단했기에 다시 만들어봤다.

다만 클라우드 배포는 생략하고 ngrok 을 사용해 외부에서 로컬서버에 접근 가능하게 설정해 테스트 했다.

 

테스트로 만든 사이트는 useEffect 에서 https://dog.ceo/api/breeds/image/random API 를 호출해 가져온 강아지 사진을 기반으로 meta tag 를 구성하도록 개발했다.
 

ngrok 으로 생성한 URL 을 Slack 채팅에 붙여넣기하니 meta tag preview 이미지가 노출되는 것을 확인할 수 있었다.

 

Slack 채팅방에 URL 을 입력한 결과

 
 

 


당시 회사에서는 Nginx 가 모든 서비스의 앞단에 있었기에 여기에서 Bot 여부를 파악해 Rendertron 서버로 라우팅 되도록 설정했다.