SEO란 Search Engine Optimization
의 약자로 단어 그대로 검색 엔진 최적화를 의미하는데, 구글이나 네이버와 같은 검색 엔진에 사이트가 더욱 잘 노출되도록 최적화 작업을 진행하는 것을 말한다. SEO를 위해 고려해야할 사항들은 다음과 같다.
html 태그 내부의 title 태그는 웹 사이트의 이름을, meta 태그는 페이지의 메타 데이터 정보를 담고있다. 메타 데이터는 여러 종류가 있지만 SEO에 가장 많은 영향을 끼치는 메타 데이터는 다음과 같다.
Next.js에서는 기본적으로 제공되는 Head 컴포넌트를 사용하여 _documents.tsx 파일 내부에 전역적으로 meta 태그를 넣거나, 메뉴마다 다른 meta 태그를 넣을 수 있고, 심지어 게시판 같이 query로 제어되는 페이지도 각각 다른 meta 태그를 넣을 수 있다.
// _document.tsx
// 전역에 넣어서 사용하는 코드
import { Html, Head, Main, NextScript } from "next/document";
export default function Document() {
return (
<Html lang="en">
<Head>
<title>Test Seo Web</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
/>
<meta property="description" content="This is Test WebSite" />
<link rel="shortcut icon" href="/favicon.ico" />
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
// pages/index.tsx
// 페이지별로 다른 title tag를 사용하는 예시.
// 해당 페이지로 진입하면 웹 사이트의 타이틀이 변경된다.
import React from "react";
import Head from "next/head";
export default function Home() {
return (
<>
<Head>
<title>title change test</title>
</Head>
<p>SEO!!</p>
</>
);
}
페이지 로딩 속도도 검색 엔진의 검색 순위에 반영된다. 따라서 SEO를 위해 페이지 로딩 속도도 최적화하는 것이 좋다. 페이지 로딩 속도를 줄이기 위해선 페이지의 리소스를 압축하거나, CDN을 사용하거나, 캐시를 설정하는 등의 방법이 있다. 다행히도 Next.js에서는 기본적으로 캐싱을 지원하고, 내장 Image
, Font
, Script
컴포넌트들을 이용해서 리소스를 최적화시키는 방법을 기본 제공한다.
Image 컴포넌트는 사용자 기기에 맞게 리소스 최적화, lazy loading, 레이아웃 오류 방지 등의 기능을 제공한다.
// image-optimization.tsx
import React from "react";
import Image from "next/image";
import TestLogo from "public/images/test-logo.png";
export async function getServerSideProps(ctx: any) {
return {
props: {},
};
}
export default function ImageTest() {
return (
<>
<Image
src={TestLogo}
alt="Test Logo"
// width={500} automatically provided
// height={500} automatically provided
// blurDataURL="data:..." automatically provided
placeholder="blur" // Optional blur-up while loading
/>
</>
);
}
Font 컴포넌트는 별도의 외부 네트워크 요청 없이 글꼴을 자동으로 최적화하는 기능을 제공한다. Google에서 제공하는 기본 font 뿐만 아니라 local에 저장된 별도의 사용자 폰트도 최적화를 지원한다.
// font-optimization.tsx
import React from "react";
import localFont from "@next/font/local";
import { JetBrains_Mono as MonoFont } from "@next/font/google";
const fontSans = localFont({
variable: "--font-sans",
src: [
{
path: "../../public/assets/fonts/NotoSansKR-Black.otf",
style: "normal",
weight: "400",
},
],
});
const monoFont = MonoFont({
subsets: ["latin"],
variable: "--font-mono",
style: "normal",
});
export async function getServerSideProps(ctx: any) {
return {
props: {},
};
}
export default function FontTest() {
return (
<>
<p style={{ fontFamily: fontSans.style.fontFamily }}>
font 1 - NotoSansKR-Black
</p>
<p style={{ fontFamily: monoFont.style.fontFamily }}>
font 2 - JetBrains_Mono
</p>
</>
);
}
필요한 곳에서만 특정 script 파일을 불러오려면 Script 컴포넌트를 사용하면 된다. 아래의 예제는 페이지에 진입할 시에 자동으로 얼럿이 호출되는 예제이다.
// script-optimization.tsx
import React from "react";
import Script from "next/script";
export async function getServerSideProps(ctx: any) {
return {
props: {},
};
}
export default function ScriptTest() {
return (
<>
<p>Script Test</p>
<Script src="scripts/test-script.js" />
</>
);
}
// script.js
function showAlert() {
alert("hello world");
}
// 스크립트가 로드되면 얼럿 호출
showAlert();
Google은 SEO를 위해 간단 명료한 URL 사용을 권고한다. 아래의 URL들은 구글이 제시한 좋은 예들이다.
Google에서는 웹 사이트 내부의 링크를 이용해 또 다른 페이지를 크롤링한다. 따라서 페이지의 링크를 통해 해당 웹 사이트의 다른 페이지를 쉽게 크롤링하게 만드는 것 또한 중요하다.
구글 크롤러는 기본적으로 올바른 href 속성이 포함된 a 태그만을 추적할 수 있는데, Next.js에서는 routing을 위해 a 태그 대신 Link
컴포넌트 사용을 강력히 권장한다. Link 컴포넌트는 기본적으로 컴파일 때 a 태그로 변환되면서 href를 지정하지만, Link 컴포넌트 내부에 별도로 자식 태그를 넣어서 커스텀화하면 경우에 따라 a 태그의 href에 빈 값이 들어갈 수도 있다.
import React from "react";
import Link from "next/link";
import styled from "styled-components";
export async function getServerSideProps(ctx: any) {
return {
props: {},
};
}
export default function LinkTest() {
return (
<>
<Link href="/image-optimization">Image Optimization</Link>
<Link href="/script-optimization">Script Optimization</Link>
<Link href="/font-optimization" passHref legacyBehavior>
<StyledLink>Font Optimization</StyledLink>
</Link>
</>
);
}
const StyledLink = styled.a`
color: red;
`;
이를 방지하려면 Link 컴포넌트의 passHref 속성을 추가하면 Link 태그 내부의 a 태그에 Link 태그의 href 값이 할당된다. 왼쪽은 passHref 사용 전, 오른쪽은 사용 후 결과값이다.
github 저장소 이동 (https://github.com/MochaChoco/seo-test)
Google 검색센터
Next.js, SEO 최적화
Next.js 환경에서 SSR을 활용하여 SEO 처리하기