새롭게 알게된 것들

Client-side rendering(CSR) 구조 웹사이트 검색엔진최적화(SEO) 적용 경험

2dubbing 2024. 8. 5. 21:54

당시 재직하던 회사에서 운영 중인 웹 프로젝트는 Create-React-App(이하 CRA) 으로 구조를 잡아 개발하고 있었다.
 
사용자가 웹사이트에 들어와 컨텐츠를 보고 기능을 사용하는데 문제는 없었으나, 웹사이트에 들어오기 전 단계에서는 문제가 있었다.
 
Client-side rendering(CSR) 가 되어 검색엔진 봇이 웹사이트 메타데이터를 크롤링하지 못하다보니, 마켓팅팀에서 기획전이나 이벤트를 위해 페이지 URL 을 외부에 공유하면 해당 사이트에 대한 요약정보 및 미리보기 이미지가 보여지지 않았다.
 
이를 해결하려면 검색엔진 봇이 우리 측 웹서버에 접근했을 때 Next.js 의 Server-side rendering(SSR) 방식처럼 서버에서 동적 컨텐츠를 포함해 페이지 rendering 을 해야했다.
 
하지만 이를 해결하고자 CRA 에서 Next.js 로 프로젝트를 마이그레이션 하기에는 시간과 개발자 리소스 측면에서 효율적이지 못하다는 생각이 들었다.
 
해결방법을 찾기위해 여러회사의 기술블로그와 인터넷검색을 하던 중, Google 개발자 블로그에서 'Rendertron 을 사용한 동적렌더링' 포스팅을 찾을 수 있었고 여기서 아이디어(?) 를 얻을 수 있었다.
https://developers.google.com/search/blog/2019/01/dynamic-rendering-with-rendertron?hl=ko
 

생각해본 방법은 다음과 같았다.

1. node.js 기반 API 서버를 구축하고 url 을 전달받아 html을 크롤링해 반환해주는 API 엔드포인트 추가한다.
2. 크롤링 로직에는 동적 스크립트를 불러와 컨텐츠 구성이 완료된 html 이 필요하기에 puppeteer 의 page.waitForSelector 를 사용해, 동적 렌더링 되면 추적가능한 element 의 selector 를 지정한다.
3. 추적이 완료되면 html meta tag 구성이 완료되었는지 puppeteer page api 를 활용해 체크하고, 웹사이트 html string 을 반환한다.
 
위 방법대로 로컬에서 간단하게 작업을 했고, 작업한 node 서버는 ngrok 을 사용해 크롤링 봇이 메타데이터를 수집할 수 있도록 설정했다.
 
ngrok 이 생성한 URL 을 Slack 채팅에 붙여넣기하니 설정한 메타데이터와 미리보기 이미지가 노출되는 것을 확인할 수 있었다!

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

 
 
당시 회사의 Web Infra 에서 rendertron 을 추가한 구조는 다음과 같았다.
 

Rendertron 이 추가된 frontend infra 구조