본문 바로가기
Front-end/React.js

Next.js에서 SEO를 최적화해보자!

by img 2023. 10. 11.

일반적으로 검색엔진이 일하는 과정

1. 크롤링

크롤링이란 검색봇이 웹페이지들을 읽으며 컨텐츠를 파싱하는 과정입니다.

크롤링 제외대상

  • 로그인 후 사용할 수 있는 페이지
  • noindex가 적용된 페이지
<meta name="robots" content="noindex">
  • rel="follow" rel="sponsored" 가 적용된 a태그 (적용되지 않으면 a태그로 연결된 페이지도 크롤링 대상으로 인식)
<a rel="nofollow" href=""></a>
<a rel="sponsored" href="">광고링크</a>

2. 렌더링

JavaScript를 실행하여 컨텐츠를 보강하는 과정입니다.

하지만 모든 크롤링 봇이 자바스크립트를 실행하는 것이 아니고, 서버사이드 렌더링이 더 빠르게 컨텐츠를 제공하기 때문에 SSR이 CSR보다 SEO에 좋습니다.

또한 자바스크립트를 실행하는 크롤링 봇이더라고 하더라도 해당 봇이 지원하는 자바스크립트 문법을 사용해야합니다.

3. 인덱싱

페이지가 가지고 있는 컨텐츠를 파악하고, 컨텐츠를 주제별로 색인하여 페이지 정보를 저장합니다.

Canonical document

동일한 또는 매우 유사한 콘텐츠를 갖는 여러 문서 중에서, 대표적인 문서를 가리키는 링크 또는 태그입니다. 여러개의 URL이 중복되어 사용될 때 검색 엔진에게 어떤 컨텐츠가 대표인지 알려주는 역할을 합니다.

<link rel="canonical" href="" />

이렇게 canonical 표시가 없는 동일 컨텐츠의 페이지가 여러개 있을 경우, 동일한 페이지를 중복으로 크롤링했다고 판단하여 해당 사이트에 대한 크롤링 빈도가 감소할 수 있습니다.

4. 랭킹

검색의도에 맞춰 인덱싱된 컨텐츠에 가장 높은 품질의 순서대로 순위를 부여한 후 결과로 제공합니다. 페이지의 컨텐츠 뿐만아니라 속도, 모바일 호환성 등이 고려됩니다.

Next.js에서 SEO 최적화 하는법

Pre-rendering

Next.js의 렌더링 방식

  • SSG : 빌드 시점에 서버에서 렌더링하는 방식
  • SSR : 요청 시점에 서버에서 렌더링하는 방식
  • ISR : 빌드 시점에 일부만 렌더링 한 후 빌드 이후에도 렌더링하는 방식
  • CSR : 사용자의 브라우저에서 렌더링하는 방식

SEO에 있어 가장 중요한 것은 JavaScript 없이 페이지 컨텐츠와 메타데이터가 페이지 로드 시에 사용가능해야 하는데, 이 경우 SSG 또는 SSR이 가장 좋은 옵션입니다.

Core Web Vitals

Core Web Vitals는 사용자 경험을 측정하기 위한 Google의 지표셋 입니다. 이 지표들은 웹 페이지의 성능과 사용자 상효작용에 초점을 맞추어 웹페이지의 품질을 평가해 SEO에 영향을 줍니다. Core Web Vitals는 다음과 같은 세가지의 주요 지표로 구성됩니다:

LCP (Largest Contentful Paint)

페이지 내에서 가장 크기가 큰 요소가 눈에 보이기까지 걸리는 시간을 측정합니다. 이 요소는 보통 페이지의 대문사진 블록, 비디오가 됩니다.

FID (First Input Delay)

사용자가 처음으로 상호작용할 수 있을 때까지 걸리는 시간을 측정합니다. 요소가 눈에는 보이지만 사용자의 상호작용에 응답하지 않을 때 사용자의 경험을 저하하게됩니다.

LightHouse에서는 FID를 측정할 수 없어 TBT(Total Blocking Time)으로 측정합니다.

CLS (Cumulative Layout Shift)

사이트의 전체적인 레이아웃 안정성을 측정합니다. DOM에 의해 초기 렌더링된 요소들이 후에 이동하는 경우에 발생하는데, 예를들어 텍스트 사이에 이미지가 렌더링 되어 텍스트가 아래로 이동하는 경우입니다.

페이지가 로드되는 동안 의도치않게 레이아웃이 변경되는 사이트는 사용자의 실수를 야기할 수 있기 때문에 사용자의 경험을 저하하게 됩니다.

<Image>

<img src="/public/logo.png" />

다음과 같이 전통적인 이미지 추가방식을 사용하면 이미지 최적화 작업을 개발자가 수동으로 해줘야합니다.

import Image from 'next/image'
<Image src="/public/logo.png" width={200} height={80} />

위처럼 Next.js에서 지원하는 <Image> 컴포넌트를 사용하면, 다음과 같은 기능을 기본적으로 지원합니다:

  • 자동 이미지 최적화: 이미지의 크기, 압축, 브라우저에 맞는 포맷 변환 등의 작업으로 최적화하여 최상의 성능을 제공합니다.
  • 반응형 이미지: 반응형으로 다양한 뷰포트 크기에 대응해 최적의 이미지를 제공합니다.
  • Lazy-loading: 페이지 로드시점에 이미지를 로드하지 않고 이미지가 화면이 나타날 때 로딩함으로써, 초기 페이지 로딩 속도를 향상시킵니다.
  • 브라우저 지원 포맷: 브라우저가 지원하는 최신 이미지 포맷 (webP 등)을 자동으로 감지하여 제공함으로써, 이미지를 더 효율적이고 빠르게 제공합니다.
  • CLS (Cumulative Layout Shift) 회피 : 이미지가 로드되기전에 레이아웃에 영향을 주는 크기 변경을 방지해 SEO에 영향을 주는 CLS를 회피하는데 도움이 됩니다.

<Link>

Next.js는 클라이언트 측에서 경로를 이동할 수 있는 <Link> 컴포넌트를 제공합니다.

import Link from 'next/link'
<Link href="challenge-flow.herokuapp.com">
	<a>여기로 이동</a>
</Link>

href 속성은 필수로 들어가야 하고 SEO에 중요한 역할을 하는 a 태그도 추가해주어야 합니다.

이 때 <Link> 의 children 이 사용자 정의 컴포넌트인 경우 <Link> 에 passHref 를 추가해주어야 합니다. 이렇게 하지 않으면 a 태그에 href 속성이 없어서 사이트의 SEO에 영향을 미칠 수 있습니다.

import Link from 'next/link'
<Link href="challenge-flow.herokuapp.com" passHref>
	<Chip>여기</Chip>
</Link>

 

Meta Tag

Meta 태그는 HTML 문서의 헤더부분에 포함되며, 웹 페이지의 메타데이터를 정의합니다. 페이지의 제목, 설명, 키워드 등의 정보를 포합하며, 이 메타데이터는 검색엔진에게 웹 페이지의 내용과 의도를 알려줌으로써 검색 결과에 영향을 미치게 됩니다.

Next.js에서는 <Head> 라는 컴포넌트를 사용하여 Meta Tag를 할당할 수 있습니다.

import Head from 'next/head';
<Head>
  <meta name="robots" content="index,follow" />
</Head>

robots.txt

robots.txt 파일은 검색엔진에게 사이트에서 접근할 수 있는 URL과 접근할 수 없는 URL을 알려주어 크롤러의 작동을 제어하는데 사용됩니다.

robots.txt 생성하는 법

루트 디렉토리의 public 폴더에 robots.txt 파일을 추가해줍니다.

<!-- public/robots.txt -->

# Block all crawlers for /accounts
User-agent: *
Disallow: /accounts

# Allow all crawlers
User-agent: *
Allow: /

 

Sitemap.xml

sitemap.xml 파일은 사이트에 있는 컨텐츠 정보를 제공하여 어떤 페이지가 중요한지 검색엔진에 알려주는 역할을 합니다. 때문에 검색엔진이 좀 더 효과적으로 크롤링 되도록 도와줍니다.

사이트맵은 검색엔진의 성능을 위해 필수는 아니지만, 크롤링과 인덱싱을 봇에게 용이하게 하여 컨텐츠가 빠르게 수집되고 그에 따라 순위가 매겨질 수 있도록 해줍니다.

Sitemap이 필요한 경우

  • 웹사이트가 매우 큰 경우
  • 웹사이트에 많은 양의 컨텐츠가 들어 있고 컨텐츠들이 서로 잘 연결되지 않는 경우
  • 새로 생긴 웹사이트이며 다른 사이트에서 해당 페이지로의 링크가 없는 경우
  • 웹사이트에 많은 양의 리치 미디어 컨텐츠(비디오, 이미지)가 있는 경우

Sitemap 작성하기

Next.js에서 sitemap을 제출하는 방법으로는 우선 아래와 같이 public/sitemap.xml 에 직접 sitemap을 작성해 넣어주는 방식이 있습니다.

<!-- public/sitemap.xml -->
 <xml version="1.0" encoding="UTF-8">
	 <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
	   <url>
	     <loc>http://www.example.com/foo</loc>
	     <lastmod>2021-06-01</lastmod>
	   </url>
	 </urlset>
 </xml>

동적으로 Sitemap 생성하기

Next.js에서는 pages의 폴더 구조를 통해 페이지를 생성하기 때문에, 이를 통해 동적으로 Sitemap을 작성할 수 있습니다.

pages/sitemap.xml.js 와 같은 새로운 페이지를 생성해 동적 페이지의 URL로 XML 파일을 만들 수 있습니다. 하지만 웹 페이지가 많은 경우 getServerSideProps는 무거운 작업을 수행하기 때문에 사용에 주의를 기울여야합니다.

import { getDynamicPageUrls } from '../utils/api';
import { createSitemapXml } from '../utils/sitemap';

export async function getServerSideProps({ res }) {
  const dynamicPageUrls = await getDynamicPageUrls();
  const sitemapXml = createSitemapXml(dynamicPageUrls);

  res.setHeader('Content-Type', 'text/xml');
  res.write(sitemapXml);
  res.end();

  return { props: {} };
}

export default function SitemapXml() {
  return null;
}

댓글