-
[Next.js] SEO 그것이 알고 싶다(NEXT의 필요성)Next.js 2023. 2. 3. 13:17
상황
22년 8월경 우리는 react.js로 운영중인 서비스를 next.js로 대대적인 마이그레이션 작업을 2개월 가량 작업 후 배포했다(중간에 직매입, 선물하기 프로젝트와 병행)
문제
물론 순탄치만은 않았다.
이렇게 큰 프로젝트의 경우 대다수의 프로젝트가 비즈니스 단의 니즈에서 시작해 기획 -> 디자인 -> 개발로 오게된다. 즉 개발팀은 시작의 주체가 아니라 제일 끝단에서 결과물을 내야하는 팀이다. 근데 이 경우 순수하게 개발팀의 니즈에 의해서 시작됐다.
물론 마일스톤 급으로 큰 프로젝트기 때문에 팀의 CTO가 경영진과 얘기를 나누어 진행하기로 했다.
그렇게 시작하게 됐지만 막상 시작하고 보니 타팀에서 이 마이그레이션을 왜 하는 지 전혀 이해하지 못하고 있었다.
심지어 이 마이그레이션의 중요 목표인 SEO 관련해서 타팀에서 개발팀을 제외하고 진행하고 있었다.
해결
이 프로젝트의 PM이자 Next 마이그레이션의 필요성을 먼저 제시하고 시작한 사람으로써 이 상황을 개선하고 싶었다.
그래서 1차적으로 개발팀에서 이 프로젝트를 왜 하는지에 대해 비개발팀이 납득할 수 있는 글을 쉽게 작성하고자 했다.
두 번째로 Next.js 마이그레이션을 통해 중요 목표인 SEO(검색엔진 최적화)를 어떻게 개선시킬 수 있는지 설명하고자 했다.
결과
다행히 많은 분들이 개발팀이 진행하고 있는 마이그레이션 프로젝트의 필요성을 이해했다고 말씀주셨다.
그리고 타팀에서 진행중인 SEO 프로젝트에 개발팀이 참여해 앞으로 같이 할 수 있는 방향성에 대해 모색하기 시작했다.
아래의 글은 타팀에 공유한 글이다.
Q) 우리 사이트를 자주 방문하고 어떤 상품을 판매하며 또 어떤 컨텐츠가 있는 지 알고 싶어 하는 분이 고객 말고 또 있다고 하는데 누굴까요 ?

바로 기계입니다!!(저 아닙니다) 알고보면 사람 뿐만 아니라 기계가 웹사이트를 읽어야 하는 경우도 굉장히 많습니다.
여기서 기계라 함은 유저가 사용하는 브라우저가 될 수 있고 웹사이트의 데이터를 수집하는 검색엔진이 될수도 있고 어떤 웹페이지의 링크를 공유하면 열기 전에 해당 콘텐츠를 미리 보여주는 SNS나 메신저도 될 수 있습니다.
그래서 ? SEO!
검색엔진이 웹사이트를 읽어서 뭐 할껀지 궁금하실 텐데, 여기서 SEO의 개념이 나옵니다.
SEO란 검색 엔진 최적화(Search Engine Optimization) 의미로 사이트를 검색 결과에 잘 노출될 수 있도록 하는 것이에요.
구글, 네이버 같은 검색엔진은 자체적으로 만든 검색봇을 이용해 수 많은 웹페이지에서 검색결과에 근접한 페이지를 최상위에 매칭해줍니다.
아하 그래서 다들 SEO, SEO 거리는거구나

끄덕끄덕 어떻게 ? 메타태그!
그래서 SEO 어떻게 하는건데 궁금하죠 ? 그건 바로 메타태그(Meta tag)로 할 수 있습니다.
검색엔진은 주기적으로 우리 웹페이지를 방문해 어떤 컨텐츠가 있는지 파악합니다.
점진적으로 기술이 발달하면서 검색엔진 스스로 어느 정도까지는 웹페이지의 구조와 내용을 파악하는 수준까지 올랐지만 그럼에도 한계가 있다고 합니다.
그렇기 때문에 메타태그를 통해 주도적으로 우리의 정보를 명시해주면 SEO(검색엔진최적화)에 유리해질 수 있다고 해요!
메타 태그란 ?
메타태그는 웹페이지가 담고 있는 컨텐츠가 아닌 웹페이지 자체의 정보를 명시하기 위한 목적으로 사용되는 HTML태그를 의미합니다.
일반 유저가 보게되는 웹페이지 컨텐츠에는 아무 영향을 주지 않지만 검색엔진과 같은 기계들이 웹페이지를 읽어야할 때 메타태그 내용들이 해당 서비스에 어떻게 표시될 지 결정하는 핵심 요소가 되거든요~!
그렇다면 대표적인 메타태그들은 어떤게 있는 지 살펴볼까요?
검색엔진 최적화를 위해 사용되는 메타 태그들을 소위 SEO 태그라고 통칭합니다.
SEO 태그 - title
그중 SEO의 가장 대표적인 태그로 title 은 웹페이지의 제목을 명시합니다.
<title>찾아오는 인생술, 술담화</title>SEO 태그 - meta
다음으로 <meta> 태그가 있는데요, 웹사이트 제목만 예외적으로 title 태그를 사용하고,
그 밖에 다른 메타 정보는 <meta> 사용합니다.
대표적인 속성을 살펴봅시다.
1. name 속성의 description을 사용해 title 요소로 담지 못했던 웹페이지에 대한 상세한 설명 담을 수 있어요
<meta name="description" content="국내 최초 전통주 술 정기 구독 서비스 쇼핑몰 술담화에서 소믈리에가 추천하는 다양한 술을 경험하세요" />2. keywords 이름을 통해 해당 웹페이지의 키워드를 나열할 수 있습니다.
<meta id="meta_nor_keywords" name="keywords" content="술담화,담화마켓,전통주,막걸리,약주,탁주,증류증,과실주,구독,전통술,전통가주,인생술,술구독,홈술,혼술,전통주구독,구독서비스,전통주정기구독,지역특산주,술스타그램,선물,술선물" />Open Graph 태그
또 다른 대표적인 속성으로 Open Graph 가 있습니다
SNS나 메신저를 통해 웹페이지의 링크를 공유하는 일이 많아지며 메타태그가 좀 더 광범위하게 쓰여지기 시작했는데요.
예를들어 카카오톡에 웹페이지 링크를 보낼 때 미리보기 카드형태로 제공하는 것이 바로 이 Open Graph를 사용한 것입니다.
1. 웹페이지의 상세 설명을 나타내는 og:description: 2. 웹페이지의 유형을 나타내는 og:type: 3. 웹페이지의 주소를 나타는 og:url: 4. 웹페이지 썸네일(thumbnail) 이미지 주소를 나타내는 og:image (권장 크기: 1200 x 630):
그렇다면 위 개념을 이해했다면
우리와 다른 회사는 어떻게 쓰고 있고 어떻게 개선할 수 있을 지 고민해 봅시다현재상황
먼저 Open Graph부터 볼까요?
1. Open Graph
1) 술담화

- meta 태그에 디폴트 이미지 정보가 잘못 들어가 있는걸 볼 수 있군요!
- 그리고 프로덕트와 상관없이 모두 똑같은 og:title, og:description, og:image url을 제공하고 있어요
- (https://www.heymeta.com/ 에서 웹사이트 메타 정보 확인가능)

페이스북 게시글 작성 시 페이스북 게시 글에 상품 링크를 넣었을 때 역시 디폴트 이미지 및 상세 정보가 안나오군요!

카카오톡 공유 시 카카오톡 공유시에는 디폴트 이미지는 나오나(캐시로 추정), 역시 프로덕트 정보를 전혀 알 수 없군요!
그렇다면 마켓컬리는 어떻게 나오는지 살펴볼까요?
2) 마켓컬리

상품 공유 시 해당 프로덕트 이미지 및 타이틀, 디스크립션까지 모두 나오는 걸 확인할 수 있어요!

다음으로 page title 과 page description을 살펴봅시당
2. Page Title / Page Description
1) 술담화

- 상세 페이지별 페이지 타이틀 및 디스크립션이 존재하지 않고 디폴트로만 들어가 있습니다.
- (https://www.rankwatch.com/free-tools/meta-tag-analyzer 에서 메타정보 확인 가능)
2) 오늘의 집

- 반면 오늘의 집은 상품별 페이지 타이틀 및 디스크립션을 달리 가져가는걸 볼 수 있어요!

문제의 원인은 어디에 있었을까요?
문제원인
1. meta Open graph 태그정의가 안되어 있어요!
- 카카오톡 미리보기 같은 경우 기존 방식대로는(CSR) 처리가 불가해요! 문의링크
2. 상품별 타이틀 및 디스크립션이 존재하지 않아요!
근데 이상하지 않나요 ?
타이틀이 위 이미지대로 분명 잘들어가 있는데 검색엔진은 왜 보지 못하는 걸까요?
그건 바로,

출처: https://www.techomoro.com/render-dynamic-title-and-meta-tags-in-a-next-js-app/ 현재의 경우 meta data를 컴포넌트 마운트 후 주입하고 있는데, 검색엔진은 페이지의 데이터가 주입될때까지 기다리지 않기때문에 메타 정보를 보지 못하게 된대요!
🔥 아하! 결국 1, 2번의 경우 모두 기존의 방식(CSR)로는 처리가 불가 했던 것이네요!!
그렇다면 문제원인도 파악했다면 어떻게 해결하고 개선할 수 있을지 살펴봅시다
해결방안
다행히도 위 문제를 해결할 수 있을 것 같아요! 개발팀이 주구장창 말했던 바로 그 Next로 말이죠!

감격!!!... (잠깐 이거 해결 못하면 어떡하지…뭐 천희님 윤기님이 해주시겠지 😂)
문제의 키는 결국 기존에 CSR로 처리해서 기계가 읽지 못했던 데이터를 SSR로 처리해, 읽을 수 있게 만드는데 있어요!
개발적으로는 아래와 같이 구현할 수 있어요!
// damhwaMarket/detail/[productId].tsx export const getServerSideProps = wrapper.getServerSideProps(store => async context => { const response = await store.dispatch(getProduct(context.query.productId)); const { name, subtext, thumbnail } = response.payload.result; const metaTags = { title: name, description: subtext, url: thumbnail, }; return { props: { metaTags, }, }; });그럼 이 정보는 _app_tsx 에서 props로 받을 수 있는데요!
이때 받은 props로 seo를 조금 더 쉽게 관리하는 라이브러리인 NextSeo 를 사용할꺼에요!
//_app.tsx { <NextSeo title={pageProps?.metaTags?.title ?? '찾아오는 인생술, 술담화'} description={ pageProps?.metaTags?.description ?? '국내 최초 전통주 술 정기 구독 서비스 쇼핑몰 술담화에서 소믈리에가 추천하는 다양한 술을 경험하세요' } openGraph={{ title: pageProps?.metaTags?.title, type: 'website', description: pageProps?.metaTags?.description ?? '국내 최초 전통주 술 정기 구독 서비스 쇼핑몰 술담화에서 소믈리에가 추천하는 다양한 술을 경험하세요', images: [ { url: pageProps?.metaTags?.url ?? 'https://sooldamhwa-static-files.s3.ap-northeast-2.amazonaws.com/thumbnail_logo.jpg', width: 200, height: 200, alt: '이미지', }, ], }} /> }props로 받은 데이터가 없다면 '찾아오는 인생술, 술담화' 등 디폴트 값을 보여주게 만들었군요!
그렇지 않다면 항상 빈값을 다시 overwrite 해버리기 때문이죠.<Head> {title && <title>{title}</title>} {description && <meta name="description" content={description} />} </Head>&& 처리로 title과 description이 생긴 후에만 주입하도록 바꿨어요!
저 처리가 없다면 기껏 SSR로 title과 description을 입혀도 다시 빈값이 입혀지겠죠?
자, 이제 어떻게 달라졌는지 살펴봅시당
개선
1. Open Graph





2. Page Title / Page Description

마무리
너무 딱딱하지 않게 짤도 넣어가며 재미나게 글을 작성 해보려고 했는데 괜찮았는지 모르겠네요
이 내용만으로는 다 알기 힘들겠지만 SEO 의 개념 및 사용방법과 저희 개발팀이 왜 힘들게 Next 로 바꾸려 하는지 조금이나마 이해하는 데 도움이 되었으면 좋겠습니다. 🙂
'Next.js' 카테고리의 다른 글
[Next.js 마이그레이션 2편] 나혼자 마이그레이션하다 (0) 2023.02.05 [Next.js 마이그레이션 1편] 프로젝트 도입배경 (0) 2023.02.04 [Next.js] On-Demand-Revalidation 고군분투 적용기 (0) 2023.01.31 [Next.js] ISR(Incremental Static Regeneration) 적용기 (0) 2023.01.30