서론
진행하고 있는 프로젝트가 슬슬 마무리 단계에 접어들었습니다. 이번 주에 1차 MVP 개발을 마치고 웹 페이지를 배포하였는데, React로 만든 프로젝트라 그런지, lighthoust에서 검색엔진 성능 테스트를 했는데 점수가 낮은 것을 확인할 수 있었습니다.
흐으음.... 가뜩이나 프로젝트 이름이 같은 사이트들이 많아 지금 이 상태로는 구글이나 네이버 같은 검색엔진에서 검색했을 때 후순위로 밀릴 가능성이 높아 보입니다ㅜㅜㅜ
그래서 검색 엔진 최적화(SEO)를 진행해 주어 점수를 높이기로 결정했습니다
SEO?
검색 엔진 최적화(Search Engine Optimization)의 줄임말로 구글이나 네이버와 같은 검색 엔진이 콘텐츠를 이해하도록 개선하고, 사용자가 내 웹 사이트를 찾을 수 있도록 최적화하는 일련의 작업을 의미합니다. SEO를 진행하게 되면 웹 페이지를 더 상위에 노출시킬 수 있게 해주어, 웹 페이지를 배포한다면 필수 작업이라고 할 수 있습니다.
그래서 어떻게?
검색 엔진을 최적화하는 방법은 여러 가지가 있습니다. 그 중 가장 간단한 방법은 nextJs와 같은 프레임워크를 통해 SSR 렌더링을 사용하는 것입니다. SSR 방식을 사용하는 경우 웹 페이지가 필요할 경우마다 서버로부터 웹 페이지를 전달받아 페이지를 띄우는 방식이기에 크롤러가 필요한 정보를 쉽게 찾을 수 있습니다. 반면 CSR의 경우 초기 빈 HTML 페이지를 전달받아 클라이언트에서 데이터 요청을 처리하기에 초기 브라우저 진입 시 크롤러가 데이터 수집에 어려움을 겪고, 이는 검색 엔진 최적화에서 불리해집니다. 이렇게만 말하면 CSR를 사용해야 할 이유가 없다고 보이지만 SEO 이외에도 각각의 장단점이 있고, 고려해야 할 요소가 많아 무조건 SSR를 사용해야 한다 이건 아니라고 생각합니다.
결과적으로 이번 프로젝트에서는 CSR 환경에서 개발중이고 SEO를 개선해야 하기에, SSR 환경으로 마이그레이션을 해야 하나 생각했는데, 여러 군데 찾아보니 구글, 네이버, 빙 정도에서만 사용한다면 굳이 SSR를 사용할 필요는 없다고 합니다.
그렇기에 NextJS로 마이그레이션 없이 React 환경에서 최대한 SEO를 진행하기로 결정했습니다.
1. SiteMap.xml 추가
첫 번째로 sitemap.xml를 추가해 주었습니다. sitemap.xml을 추가하면 크롤러가 보다 쉽게 웹 페이지를 발견할 수 있기에 노출되어야 하는 페이지들을 추가해 주었습니다. https://www.xml-sitemaps.com/ 이러한 sitemap generator을 이용해 sitemap.xml을 생성할 수도 있지만 CSR 환경에서 개발하는 경우 루트 주소에 대한 uri만 추가해 주기 때문에 저는 직접 만들어서 사용하였습니다.
<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<!-- created with Free Online Sitemap Generator www.xml-sitemaps.com -->
<url>
<loc>https://www.haeyum.kr/</loc>
<lastmod>2025-01-29</lastmod>
</url>
<url>
<loc>https://www.haeyum.kr/search</loc>
<lastmod>2025-01-29</lastmod>
</url>
<url>
<loc>https://www.haeyum.kr/chats</loc>
<lastmod>2025-01-29</lastmod>
</url>
<url>
<loc>https://www.haeyum.kr/profile</loc>
<lastmod>2025-01-29</lastmod>
</url>
</urlset>
2. Robots.txt 추가
두 번째로 robots.txt를 추가해주었습니다. robots.txt는 크롤러에게 사이트 맵 정보를 전달하는 역할을 하기에 필수로 추가해 주어야 합니다.
User-agent: *
Allow: /
Sitemap: https://www.haeyum.kr/sitemap.xml
이렇게 작성한 sitemap.xml과 robots.txt를 src/public 폴더에 추가해주어 빌드 시 포함될 수 있도록 하였습니다. 혹은 배포한 곳의 루트 디렉터리에 직접 추가해도 무방합니다.
3. 메타 태그 추가
마지막으로 매타 태그를 추가해주었습니다. 매타 태그는 그 페이지가 어떤 역할을 하는지 정보를 주는 역할을 하고, 크롤러가 메타 태그에 있는 정보를 이용해 미리 보기를 제공하거나 그 페이지가 어떤 페이지인지 확인하는 역할을 합니다.
그렇기에 메타 태그를 추가해주었습니다.
React의 경우 앞서 말했다시피 CSR 기반이기에 설정할 수 있는 정적 페이지가 index.html 하나뿐입니다. 그렇기에 페이지마다 직접 메타 태그를 추가해주어야 합니다.
저는 react-helmet-async이라는 라이브러리를 사용해 페이지별 메타 태그를 추가해 주었습니다.
먼저 추가할 메타 태그를 골라 주었고,
그다음으로 사용될 메타 태그가 모두 똑같은 형태를 가지기에 이를 공용 컴포넌트로 만드는 작업을 하였습니다.
import { Helmet } from 'react-helmet-async';
interface Props {
title: string;
description: string;
keywords: string;
}
const MetaTag = (props: Props) => {
const { title, description, keywords } = props;
return (
<Helmet>
<title>{title}</title>
<meta name="description" content={description} />
<meta name="keywords" content={keywords} />
<meta property="og:type" content="website" />
<meta property="og:title" content={title} />
<meta property="og:site_name" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={'/src/common/assets/logo/logo.svg'} />
<meta property="og:url" content={window.location.href} />
<link rel="canonical" href={window.location.href} />
</Helmet>
);
};
export default MetaTag;
이렇게 공용 컴포넌트를 만들어 주었고, 이를 사용하여 아래 코드처럼 페이지마다 메타 태그를 추가해 주었습니다.
const Layout = ({ children }: { children: ReactNode }) => {
return (
<>
<MetaTag
title="헤윰 - 채팅목록"
description="참여 중인 채팅방을 확인하고, 새로운 대화를 시작해 보세요!"
keywords="채팅, 대화, 시간 여행, 헤윰"
/>
<AppBar text="채팅" />
<Container>{children}</Container>
</>
);
};
export default Layout;
아래 사진들을 보면 페이지마다 메타 태그가 정상적으로 삽입된 것을 확인할 수 있습니다.
결과
이렇게 3가지의 SEO를 진행해 주었고, 다시 SEO 성능 테스트를 해봤을 때 점수가 좋아진 것을 확인할 수 있었습니다.
후기
배포만 하면 마무리가 되는 줄 알았는데 신경 써야 할 부분들이 너무 많았다 ㅜㅜㅜㅜ
'React' 카테고리의 다른 글
[React] 재사용 가능한 AppBar 제작하기 (0) | 2025.01.13 |
---|---|
[Eslint] Eslint flat config 적용기 (0) | 2025.01.12 |
[React] 라이브러리 없이 캘린더 컴포넌트 구현하기 (0) | 2025.01.11 |
[React] Kakao Map Api 사용하기 (5) - debounce를 활용한 Api 호출 최적화하기 (1) | 2024.09.15 |
[React] Kakao Map API 사용하기 (4) - customoverlay 클릭 이벤트 등록하기 (1) | 2024.08.30 |