๐Ÿš€ Gatsby ๋ธ”๋กœ๊ทธ ๊ฒ€์ƒ‰ ์—”์ง„ ๋ฐฐํฌ

@leekh8 ยท April 25, 2024 ยท 16 min read

Code N Solve ๐Ÿ“˜: Gatsby ๋ธ”๋กœ๊ทธ ๋ฐฐํฌ

Netlify๋ฅผ ์ด์šฉํ•ด ๋ฐฐํฌํ•˜๋Š” ๊ฒƒ์€ ํŽธํ•˜์ง€๋งŒ ์ง์ ‘ ํ•ด๋ณด๋Š” ๊ฒƒ์ด ๋” ์žฌ๋ฏธ์žˆ๊ฒ ๋‹ค๊ณ  ๋А๊ปด์กŒ๋‹ค.1

Gatsby๋ฅผ ์ด์šฉํ•œ ์›น์‚ฌ์ดํŠธ์˜ ๋ฐฐํฌ ๊ณผ์ •๊ณผ ๊ฒ€์ƒ‰ ์—”์ง„ ์ตœ์ ํ™”(SEO) ์„ค์ •์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด๋ณด์ž. ์ด ๊ธ€์€ ์ด๋ฏธ Gatsby ๋ธ”๋กœ๊ทธ๋ฅผ GitHub Pages๋‚˜ Netlify์— ๋ฐฐํฌํ•œ ์ƒํƒœ๋ฅผ ์ „์ œ๋กœ ํ•œ๋‹ค. ๋ฐฐํฌ๊นŒ์ง€๋Š” ์™„๋ฃŒ๋๋Š”๋ฐ ๊ตฌ๊ธ€์— ๋‚ด ๋ธ”๋กœ๊ทธ๊ฐ€ ๋ณด์ด์ง€ ์•Š๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด, ์ด ๊ธ€์ด ๋„์›€์ด ๋  ๊ฒƒ์ด๋‹ค.


1. SEO๋ž€? โ€” ๊ฒ€์ƒ‰ ์—”์ง„์˜ ๋™์ž‘ ์›๋ฆฌ๋ถ€ํ„ฐ

1-1. SEO์˜ ์ •์˜

SEO(Search Engine Optimization)๋Š” ์›น์‚ฌ์ดํŠธ๊ฐ€ ๊ตฌ๊ธ€, ๋„ค์ด๋ฒ„ ๊ฐ™์€ ๊ฒ€์ƒ‰ ์—”์ง„์—์„œ ๋” ์ž˜ ๋…ธ์ถœ๋˜๋„๋ก ์ตœ์ ํ™”ํ•˜๋Š” ์ž‘์—…์ด๋‹ค. ๋‹จ์ˆœํžˆ ํ‚ค์›Œ๋“œ๋ฅผ ๋งŽ์ด ๋„ฃ๋Š” ๊ธฐ์ˆ ์ด ์•„๋‹ˆ๋ผ, ๊ฒ€์ƒ‰ ์—”์ง„์ด ์‚ฌ์ดํŠธ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ดํ•ดํ•˜๊ณ  ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š” ์ „๋ฐ˜์ ์ธ ์ž‘์—…์„ ๋งํ•œ๋‹ค.

1-2. ๊ฒ€์ƒ‰ ์—”์ง„์˜ ์„ธ ๊ฐ€์ง€ ๋‹จ๊ณ„

๊ฒ€์ƒ‰ ์—”์ง„์ด ๋‚ด ๋ธ”๋กœ๊ทธ๋ฅผ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ์— ๋ณด์—ฌ์ฃผ๊ธฐ๊นŒ์ง€ ์„ธ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์นœ๋‹ค.

1๋‹จ๊ณ„: ํฌ๋กค๋ง(Crawling)

๊ฒ€์ƒ‰ ์—”์ง„์€ "ํฌ๋กค๋Ÿฌ(Crawler)" ํ˜น์€ "๋ด‡(Bot)"์ด๋ผ ๋ถˆ๋ฆฌ๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ํ†ตํ•ด ์ธํ„ฐ๋„ท์„ ํƒ์ƒ‰ํ•œ๋‹ค. ๊ตฌ๊ธ€์˜ ํฌ๋กค๋Ÿฌ๋Š” "Googlebot"์ด๋ผ๊ณ  ๋ถˆ๋ฆฐ๋‹ค. ํฌ๋กค๋Ÿฌ๋Š” ๋งํฌ๋ฅผ ๋”ฐ๋ผ ํŽ˜์ด์ง€๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ณ  ํŽ˜์ด์ง€ ๋‚ด์šฉ์„ ์ˆ˜์ง‘ํ•œ๋‹ค.

ํฌ๋กค๋ง์ด ์ž˜ ๋˜๋ ค๋ฉด:

  • ์‚ฌ์ดํŠธ ๊ตฌ์กฐ๊ฐ€ ๋ช…ํ™•ํ•ด์•ผ ํ•œ๋‹ค (๋งํฌ๊ฐ€ ์ž˜ ์—ฐ๊ฒฐ๋ผ ์žˆ์–ด์•ผ ํ•จ)
  • robots.txt๋กœ ํฌ๋กค๋Ÿฌ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•ด์•ผ ํ•œ๋‹ค
  • sitemap.xml์„ ์ œ๊ณตํ•ด ํฌ๋กค๋Ÿฌ๊ฐ€ ํŽ˜์ด์ง€ ๋ชฉ๋ก์„ ํ•œ๋ˆˆ์— ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค

2๋‹จ๊ณ„: ์ธ๋ฑ์‹ฑ(Indexing)

ํฌ๋กค๋Ÿฌ๊ฐ€ ์ˆ˜์ง‘ํ•œ ํŽ˜์ด์ง€ ๋‚ด์šฉ์„ ๋ถ„์„ํ•ด ๊ฒ€์ƒ‰ ์—”์ง„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๋Š” ๊ณผ์ •์ด๋‹ค. ํŽ˜์ด์ง€ ์ œ๋ชฉ, ๋ณธ๋ฌธ, ๋ฉ”ํƒ€ ํƒœ๊ทธ, ์ด๋ฏธ์ง€ ๋“ฑ์„ ๋ถ„์„ํ•ด ํ•ด๋‹น ํŽ˜์ด์ง€๊ฐ€ ์–ด๋–ค ์ฃผ์ œ๋ฅผ ๋‹ค๋ฃจ๋Š”์ง€ ํŒŒ์•…ํ•œ๋‹ค.

์ธ๋ฑ์‹ฑ์ด ์ž˜ ๋˜๋ ค๋ฉด:

  • ๋ฉ”ํƒ€ ํƒœ๊ทธ(title, description)๊ฐ€ ๋ช…ํ™•ํ•ด์•ผ ํ•œ๋‹ค
  • ํŽ˜์ด์ง€ ๋‚ด์šฉ์ด ์ถฉ๋ถ„ํžˆ ํ’๋ถ€ํ•ด์•ผ ํ•œ๋‹ค
  • ์ค‘๋ณต ์ฝ˜ํ…์ธ ๊ฐ€ ์—†์–ด์•ผ ํ•œ๋‹ค

3๋‹จ๊ณ„: ๋žญํ‚น(Ranking)

์‚ฌ์šฉ์ž๊ฐ€ ๊ฒ€์ƒ‰์–ด๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๋•Œ ์–ด๋–ค ํŽ˜์ด์ง€๋ฅผ ๋ช‡ ๋ฒˆ์งธ์— ๋ณด์—ฌ์ค„์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๊ณผ์ •์ด๋‹ค. ๊ตฌ๊ธ€์€ 200๊ฐœ ์ด์ƒ์˜ ๋žญํ‚น ์‹ ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์•Œ๋ ค์ ธ ์žˆ๋‹ค. ๋Œ€ํ‘œ์ ์ธ ์š”์†Œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • ์ฝ˜ํ…์ธ  ๊ด€๋ จ์„ฑ: ๊ฒ€์ƒ‰์–ด์™€ ํŽ˜์ด์ง€ ๋‚ด์šฉ์ด ์–ผ๋งˆ๋‚˜ ์ผ์น˜ํ•˜๋Š”๊ฐ€
  • ํŽ˜์ด์ง€ ํ’ˆ์งˆ: ๋‚ด์šฉ์ด ์ถฉ๋ถ„ํ•˜๊ณ  ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ๋Š”๊ฐ€
  • ํŽ˜์ด์ง€ ๊ฒฝํ—˜: ๋กœ๋”ฉ ์†๋„, ๋ชจ๋ฐ”์ผ ์นœํ™”์„ฑ, Core Web Vitals
  • ๋ฐฑ๋งํฌ: ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ์—์„œ ์–ผ๋งˆ๋‚˜ ๋งŽ์ด ๋งํฌํ•˜๋Š”๊ฐ€

1-3. ์™œ Gatsby๋Š” SEO์— ์œ ๋ฆฌํ•œ๊ฐ€?

React ๊ธฐ๋ฐ˜ SPA(Single Page Application)๋Š” JavaScript๊ฐ€ ์‹คํ–‰๋˜์–ด์•ผ ์ฝ˜ํ…์ธ ๊ฐ€ ๋ Œ๋”๋ง๋œ๋‹ค. ๊ณผ๊ฑฐ ๊ตฌ๊ธ€๋ด‡์€ JavaScript ์‹คํ–‰ ๋Šฅ๋ ฅ์ด ์ œํ•œ์ ์ด์—ˆ๊ธฐ ๋•Œ๋ฌธ์— SPA๋Š” SEO์— ๋ถˆ๋ฆฌํ–ˆ๋‹ค.

Gatsby๋Š” **์ •์  ์‚ฌ์ดํŠธ ์ƒ์„ฑ๊ธฐ(Static Site Generator)**๋กœ, ๋นŒ๋“œ ์‹œ์ ์— HTML ํŒŒ์ผ์„ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•œ๋‹ค. ์ด๋ฅผ ์‚ฌ์ „ ๋ Œ๋”๋ง(Pre-rendering) ๋˜๋Š” **SSG(Static Site Generation)**๋ผ๊ณ  ํ•œ๋‹ค.

์ผ๋ฐ˜ React SPA:
๋ธŒ๋ผ์šฐ์ € โ†’ JavaScript ๋‹ค์šด๋กœ๋“œ โ†’ React ์‹คํ–‰ โ†’ HTML ์ƒ์„ฑ โ†’ ํ™”๋ฉด ์ถœ๋ ฅ

Gatsby:
๋นŒ๋“œ ์‹œ์ ์— HTML ๋ฏธ๋ฆฌ ์ƒ์„ฑ โ†’ ๋ธŒ๋ผ์šฐ์ €์— ๋ฐ”๋กœ HTML ์ „๋‹ฌ โ†’ ํ™”๋ฉด ์ถœ๋ ฅ

HTML์ด ์ด๋ฏธ ๋งŒ๋“ค์–ด์ ธ ์žˆ์œผ๋ฏ€๋กœ ๊ตฌ๊ธ€๋ด‡์ด JavaScript ์‹คํ–‰ ์—†์ด๋„ ๋ฐ”๋กœ ์ฝ˜ํ…์ธ ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค. SEO์— ์œ ๋ฆฌํ•˜๊ณ , ์ดˆ๊ธฐ ๋กœ๋”ฉ ์†๋„๋„ ๋น ๋ฅด๋‹ค.


2. Gatsby SEO ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์ •

Gatsby๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ ์ƒํƒœ๊ณ„๊ฐ€ ํ’๋ถ€ํ•˜๋‹ค. SEO์— ํ•„์š”ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•˜๊ณ  ์„ค์ •ํ•˜์ž.

2-1. ํ•„์š”ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ชฉ๋ก

npm install gatsby-plugin-sitemap gatsby-plugin-robots-txt gatsby-plugin-react-helmet react-helmet
ํ”Œ๋Ÿฌ๊ทธ์ธ ์—ญํ• 
gatsby-plugin-sitemap sitemap.xml ์ž๋™ ์ƒ์„ฑ
gatsby-plugin-robots-txt robots.txt ์ž๋™ ์ƒ์„ฑ
gatsby-plugin-react-helmet <head> ํƒœ๊ทธ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ
react-helmet gatsby-plugin-react-helmet์˜ ์˜์กด์„ฑ

2-2. gatsby-config.js ์„ค์ •

// gatsby-config.js
module.exports = {
  siteMetadata: {
    title: `๋‚ด ๋ธ”๋กœ๊ทธ`,
    description: `๊ฐœ๋ฐœ ๊ณต๋ถ€ ๊ธฐ๋ก ๋ธ”๋กœ๊ทธ`,
    author: `leekh8`,
    siteUrl: `https://leekh8.github.io`,  // ๋ฐ˜๋“œ์‹œ ์‹ค์ œ URL๋กœ
  },
  plugins: [
    // React Helmet: <head> ํƒœ๊ทธ ๊ด€๋ฆฌ
    `gatsby-plugin-react-helmet`,

    // Sitemap ์ƒ์„ฑ
    {
      resolve: `gatsby-plugin-sitemap`,
      options: {
        output: `/sitemap.xml`,
        // ํŠน์ • ํŽ˜์ด์ง€ ์ œ์™ธ ์˜ˆ์‹œ
        excludes: [
          `/dev-404-page`,
          `/404`,
          `/404.html`,
        ],
      },
    },

    // robots.txt ์ƒ์„ฑ
    {
      resolve: `gatsby-plugin-robots-txt`,
      options: {
        host: `https://leekh8.github.io`,
        sitemap: `https://leekh8.github.io/sitemap.xml`,
        policy: [
          { userAgent: `*`, allow: `/` },
        ],
      },
    },
  ],
};

siteUrl์€ ๋ฐ˜๋“œ์‹œ ์‹ค์ œ ๋ฐฐํฌ ๋„๋ฉ”์ธ์œผ๋กœ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค. sitemap.xml์— ๋“ค์–ด๊ฐ€๋Š” URL์ด ์ด ๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค.

2-3. SEO ์ปดํฌ๋„ŒํŠธ ๋งŒ๋“ค๊ธฐ

๊ฐ ํŽ˜์ด์ง€๋งˆ๋‹ค ๋ฉ”ํƒ€ ํƒœ๊ทธ๋ฅผ ์ผ๊ด€์„ฑ ์žˆ๊ฒŒ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด SEO ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ ๋‹ค.

// src/components/SEO.jsx
import React from "react";
import { Helmet } from "react-helmet";
import { useStaticQuery, graphql } from "gatsby";

const SEO = ({ title, description, image, pathname }) => {
  const data = useStaticQuery(graphql`
    query {
      site {
        siteMetadata {
          title
          description
          author
          siteUrl
        }
      }
    }
  `);

  const siteMetadata = data.site.siteMetadata;
  const metaTitle = title || siteMetadata.title;
  const metaDescription = description || siteMetadata.description;
  const metaImage = image
    ? `${siteMetadata.siteUrl}${image}`
    : `${siteMetadata.siteUrl}/og-image.png`;
  const metaUrl = pathname
    ? `${siteMetadata.siteUrl}${pathname}`
    : siteMetadata.siteUrl;

  return (
    <Helmet>
      {/* ๊ธฐ๋ณธ ๋ฉ”ํƒ€ ํƒœ๊ทธ */}
      <title>{metaTitle}</title>
      <meta name="description" content={metaDescription} />

      {/* Open Graph ๋ฉ”ํƒ€ ํƒœ๊ทธ (SNS ๊ณต์œ ์šฉ) */}
      <meta property="og:title" content={metaTitle} />
      <meta property="og:description" content={metaDescription} />
      <meta property="og:image" content={metaImage} />
      <meta property="og:url" content={metaUrl} />
      <meta property="og:type" content="website" />
      <meta property="og:site_name" content={siteMetadata.title} />

      {/* Twitter Card ๋ฉ”ํƒ€ ํƒœ๊ทธ */}
      <meta name="twitter:card" content="summary_large_image" />
      <meta name="twitter:title" content={metaTitle} />
      <meta name="twitter:description" content={metaDescription} />
      <meta name="twitter:image" content={metaImage} />

      {/* ๊ธฐํƒ€ */}
      <link rel="canonical" href={metaUrl} />
    </Helmet>
  );
};

export default SEO;

์ด ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐ ํŽ˜์ด์ง€ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋ถˆ๋Ÿฌ์™€ ์‚ฌ์šฉํ•œ๋‹ค.

// ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ ํ…œํ”Œ๋ฆฟ ์˜ˆ์‹œ
const BlogPost = ({ data }) => {
  const post = data.markdownRemark;
  return (
    <>
      <SEO
        title={post.frontmatter.title}
        description={post.frontmatter.description}
        pathname={`/posts/${post.fields.slug}`}
      />
      <article>
        <h1>{post.frontmatter.title}</h1>
        <div dangerouslySetInnerHTML={{ __html: post.html }} />
      </article>
    </>
  );
};

3. robots.txt ์„ค์ •

3-1. robots.txt๋ž€?

robots.txt๋Š” ํฌ๋กค๋Ÿฌ(๋ด‡)์—๊ฒŒ ์–ด๋–ค ํŽ˜์ด์ง€๋ฅผ ํฌ๋กค๋งํ•ด๋„ ๋˜๊ณ , ์–ด๋–ค ํŽ˜์ด์ง€๋Š” ํ•˜์ง€ ๋ง์•„์•ผ ํ•˜๋Š”์ง€ ์•Œ๋ ค์ฃผ๋Š” ํŒŒ์ผ์ด๋‹ค. ์‚ฌ์ดํŠธ ๋ฃจํŠธ์— ์œ„์น˜ํ•ด์•ผ ํ•œ๋‹ค (https://yourdomain.com/robots.txt).

3-2. robots.txt ๋ฌธ๋ฒ•

# ๋ชจ๋“  ํฌ๋กค๋Ÿฌ์—๊ฒŒ ๋ชจ๋“  ๊ฒฝ๋กœ ํ—ˆ์šฉ
User-agent: *
Allow: /

# Googlebot์—๊ฒŒ๋งŒ ํŠน์ • ๊ฒฝ๋กœ ๋น„ํ—ˆ์šฉ
User-agent: Googlebot
Disallow: /private/

# ์‚ฌ์ดํŠธ๋งต ์œ„์น˜ ์•Œ๋ ค์ฃผ๊ธฐ
Sitemap: https://leekh8.github.io/sitemap.xml
๋””๋ ‰ํ‹ฐ๋ธŒ ์„ค๋ช…
User-agent ์–ด๋–ค ๋ด‡์— ์ ์šฉํ• ์ง€ (*๋Š” ๋ชจ๋“  ๋ด‡)
Allow ์ ‘๊ทผ ํ—ˆ์šฉ ๊ฒฝ๋กœ
Disallow ์ ‘๊ทผ ๊ธˆ์ง€ ๊ฒฝ๋กœ
Sitemap ์‚ฌ์ดํŠธ๋งต ์œ„์น˜

3-3. ๊ฐœ์ธ ๋ธ”๋กœ๊ทธ์—์„œ ๊ถŒ์žฅํ•˜๋Š” ์„ค์ •

User-agent: *
Allow: /
Sitemap: https://leekh8.github.io/sitemap.xml

๊ฐœ์ธ ๋ธ”๋กœ๊ทธ๋Š” ๋Œ€๋ถ€๋ถ„ ๋ชจ๋“  ํŽ˜์ด์ง€๋ฅผ ๋…ธ์ถœ์‹œํ‚ค๊ณ  ์‹ถ์œผ๋ฏ€๋กœ ์ „์ฒด ํ—ˆ์šฉ์ด ๊ธฐ๋ณธ์ด๋‹ค. ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€๋‚˜ ๋น„๊ณต๊ฐœ ํŽ˜์ด์ง€๊ฐ€ ์žˆ๋‹ค๋ฉด Disallow๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

3-4. GitHub Pages์—์„œ static ํด๋” ํ™œ์šฉ

gatsby-plugin-robots-txt๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋นŒ๋“œ ์‹œ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค. ์ˆ˜๋™์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ ค๋ฉด static ํด๋”์— ํŒŒ์ผ์„ ๋„ฃ์œผ๋ฉด Gatsby๊ฐ€ ๋นŒ๋“œ ์‹œ public ํด๋”๋กœ ๋ณต์‚ฌํ•œ๋‹ค.

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ:
/static/robots.txt  โ†’  ๋นŒ๋“œ ์‹œ /public/robots.txt๋กœ ๋ณต์‚ฌ๋จ

/static ํด๋”์— ์žˆ๋Š” ํŒŒ์ผ์€ ๋ณ€ํ™˜ ์—†์ด ๊ทธ๋Œ€๋กœ public์œผ๋กœ ๋ณต์‚ฌ๋œ๋‹ค. HTML ํŒŒ์ผ์„ ์ด์šฉํ•œ ์†Œ์œ ๊ถŒ ์ธ์ฆ ํŒŒ์ผ๋„ ์ด ๋ฐฉ๋ฒ•์œผ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค.


4. sitemap.xml ์ƒ์„ฑ ๋ฐ ํ™•์ธ

4-1. sitemap.xml์ด๋ž€?

sitemap.xml์€ ์‚ฌ์ดํŠธ ๋‚ด์˜ ๋ชจ๋“  ํŽ˜์ด์ง€ URL ๋ชฉ๋ก์„ XML ํ˜•์‹์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ํŒŒ์ผ์ด๋‹ค. ํฌ๋กค๋Ÿฌ๊ฐ€ ์ด ํŒŒ์ผ์„ ๋ณด๊ณ  ์–ด๋–ค ํŽ˜์ด์ง€๊ฐ€ ์žˆ๋Š”์ง€ ๋น ๋ฅด๊ฒŒ ํŒŒ์•…ํ•œ๋‹ค.

<!-- sitemap.xml ์˜ˆ์‹œ -->
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://leekh8.github.io/</loc>
    <lastmod>2024-04-25</lastmod>
    <changefreq>daily</changefreq>
    <priority>1.0</priority>
  </url>
  <url>
    <loc>https://leekh8.github.io/posts/my-first-post/</loc>
    <lastmod>2024-04-20</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.8</priority>
  </url>
</urlset>
ํƒœ๊ทธ ์„ค๋ช…
<loc> ํŽ˜์ด์ง€ URL (ํ•„์ˆ˜)
<lastmod> ๋งˆ์ง€๋ง‰ ์ˆ˜์ •์ผ
<changefreq> ๋ณ€๊ฒฝ ๋นˆ๋„ (always, hourly, daily, weekly, monthly, yearly, never)
<priority> ์šฐ์„ ์ˆœ์œ„ (0.0 ~ 1.0, ๊ธฐ๋ณธ๊ฐ’ 0.5)

4-2. gatsby-plugin-sitemap์œผ๋กœ ์ž๋™ ์ƒ์„ฑ

gatsby build ํ›„ public/sitemap.xml ํŒŒ์ผ์ด ์ƒ์„ฑ๋œ๋‹ค. ๋ฐฐํฌ ํ›„ https://yourdomain.com/sitemap.xml๋กœ ์ ‘๊ทผํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

4-3. sitemap.xml ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ

์ƒ์„ฑ๋œ sitemap์ด ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•:

  1. ๋ธŒ๋ผ์šฐ์ €์—์„œ https://yourdomain.com/sitemap.xml ์ง์ ‘ ์—ด๊ธฐ
  2. XML Sitemap Validator์—์„œ URL ์ž…๋ ฅ
  3. Google Search Console์˜ Sitemap ์„น์…˜์— ์ œ์ถœ ํ›„ ์˜ค๋ฅ˜ ํ™•์ธ

5. Google Search Console ๋“ฑ๋ก ์ „์ฒด ๊ณผ์ •

5-1. Google Search Console์ด๋ž€?

Google Search Console(์ดํ•˜ GSC)์€ ๊ตฌ๊ธ€์ด ๋ฌด๋ฃŒ๋กœ ์ œ๊ณตํ•˜๋Š” ๋„๊ตฌ๋‹ค. ๋‚ด ์‚ฌ์ดํŠธ๊ฐ€ ๊ตฌ๊ธ€ ๊ฒ€์ƒ‰์— ์–ด๋–ป๊ฒŒ ๋…ธ์ถœ๋˜๋Š”์ง€, ์–ด๋–ค ํ‚ค์›Œ๋“œ๋กœ ์œ ์ž…๋˜๋Š”์ง€, ํฌ๋กค๋ง ์˜ค๋ฅ˜๋Š” ์—†๋Š”์ง€ ๋“ฑ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

5-2. ์†์„ฑ ์œ ํ˜• ์„ ํƒ

GSC์— ์‚ฌ์ดํŠธ๋ฅผ ๋“ฑ๋กํ•  ๋•Œ ๋‘ ๊ฐ€์ง€ ์†์„ฑ ์œ ํ˜• ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ ํƒํ•œ๋‹ค.

๋„๋ฉ”์ธ ์†์„ฑ (Domain property)

  • ๋ชจ๋“  ์„œ๋ธŒ๋„๋ฉ”์ธ๊ณผ ํ”„๋กœํ† ์ฝœ(http/https)์„ ํฌํ•จํ•ด ํ†ตํ•ฉ ๊ด€๋ฆฌ
  • DNS TXT ๋ ˆ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ๋งŒ ์ธ์ฆ ๊ฐ€๋Šฅ
  • GitHub Pages๋Š” GitHub ์ธก์—์„œ DNS๋ฅผ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ DNS ๋ ˆ์ฝ”๋“œ ์ˆ˜์ •์ด ๋ถˆ๊ฐ€๋Šฅ โ†’ ์‚ฌ์šฉ ๋ถˆ๊ฐ€

URL ์ ‘๋‘์–ด ์†์„ฑ (URL-prefix property)

  • ํŠน์ • URL ํ˜•์‹์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ์ˆ˜์ง‘
  • HTML ํŒŒ์ผ ์—…๋กœ๋“œ, HTML ๋ฉ”ํƒ€ ํƒœ๊ทธ ์‚ฝ์ž… ๋“ฑ ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ธ์ฆ ๊ฐ€๋Šฅ
  • GitHub Pages ์‚ฌ์šฉ์ž์—๊ฒŒ ์ ํ•ฉํ•œ ๋ฐฉ์‹

5-3. HTML ํŒŒ์ผ ๋ฐฉ์‹์œผ๋กœ ์†Œ์œ ๊ถŒ ์ธ์ฆ

  1. Google Search Console์— ์ ‘์†
  2. ์†์„ฑ ์ถ”๊ฐ€ โ†’ "URL ์ ‘๋‘์–ด" ์„ ํƒ โ†’ ์ž์‹ ์˜ GitHub Pages URL ์ž…๋ ฅ (์˜ˆ: https://leekh8.github.io)
  3. "HTML ํŒŒ์ผ" ๋ฐฉ๋ฒ• ์„ ํƒ โ†’ googleXXXXXXXXXXXXXXXX.html ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ
  4. ๋‹ค์šด๋กœ๋“œํ•œ ํŒŒ์ผ์„ Gatsby ํ”„๋กœ์ ํŠธ์˜ /static ํด๋”์— ๋„ฃ๊ธฐ
project/
โ”œโ”€โ”€ static/
โ”‚   โ””โ”€โ”€ googleXXXXXXXXXXXXXXXX.html  โ† ์—ฌ๊ธฐ์— ๋„ฃ๊ธฐ
โ”œโ”€โ”€ src/
โ””โ”€โ”€ gatsby-config.js
  1. gatsby build โ†’ GitHub์— ํ‘ธ์‹œ โ†’ GitHub Actions ๋ฐฐํฌ ์™„๋ฃŒ ํ›„
  2. GSC๋กœ ๋Œ์•„์™€ "ํ™•์ธ" ๋ฒ„ํŠผ ํด๋ฆญ

static ํด๋”์— ํŒŒ์ผ์„ ๋„ฃ์œผ๋ฉด Gatsby ๋นŒ๋“œ ์‹œ public ํด๋”๋กœ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐฐํฌ ํ›„ https://leekh8.github.io/googleXXXXXXXXXXXXXXXX.html๋กœ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

5-4. HTML ๋ฉ”ํƒ€ ํƒœ๊ทธ ๋ฐฉ์‹์œผ๋กœ ์†Œ์œ ๊ถŒ ์ธ์ฆ

๋ฉ”ํƒ€ ํƒœ๊ทธ ๋ฐฉ์‹์€ ํŒŒ์ผ์„ ๋”ฐ๋กœ ๋ฐฐํฌํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. SEO ์ปดํฌ๋„ŒํŠธ์— ํƒœ๊ทธ ํ•˜๋‚˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

// src/components/SEO.jsx ์— ์ถ”๊ฐ€
<Helmet>
  {/* Google Search Console ์†Œ์œ ๊ถŒ ์ธ์ฆ ํƒœ๊ทธ */}
  <meta name="google-site-verification" content="YOUR_VERIFICATION_CODE" />
  
  {/* ๊ธฐ์กด ๋ฉ”ํƒ€ ํƒœ๊ทธ๋“ค... */}
</Helmet>

๋‹จ, ์ด ๋ฐฉ๋ฒ•์€ SEO ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ชจ๋“  ํŽ˜์ด์ง€์— ๋ Œ๋”๋ง๋˜๋„๋ก ์„ค์ •๋ผ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

5-5. sitemap ์ œ์ถœ

์†Œ์œ ๊ถŒ ์ธ์ฆ ํ›„, sitemap์„ GSC์— ์ œ์ถœํ•˜๋ฉด ๊ตฌ๊ธ€์ด ๋” ๋น ๋ฅด๊ฒŒ ํŽ˜์ด์ง€๋ฅผ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. GSC ์ขŒ์ธก ๋ฉ”๋‰ด โ†’ "Sitemaps"
  2. "์ƒˆ ์‚ฌ์ดํŠธ๋งต ์ถ”๊ฐ€" ์ž…๋ ฅ๋ž€์— sitemap.xml ์ž…๋ ฅ
  3. "์ œ์ถœ" ํด๋ฆญ

์ œ์ถœ ํ›„ "์„ฑ๊ณต"์œผ๋กœ ํ‘œ์‹œ๋˜๋ฉด ๋œ๋‹ค. ์ฒ˜๋ฆฌ์—๋Š” ๋ช‡ ์‹œ๊ฐ„์—์„œ ๋ฉฐ์น ์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

5-6. GSC์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ์ •๋ณด

  • ์‹ค์ (Performance): ๊ฒ€์ƒ‰ ๋…ธ์ถœ ์ˆ˜, ํด๋ฆญ ์ˆ˜, ํ‰๊ท  ์ˆœ์œ„, CTR
  • URL ๊ฒ€์‚ฌ: ํŠน์ • URL์˜ ์ƒ‰์ธ ์ƒํƒœ ํ™•์ธ ๋ฐ ์ƒ‰์ธ ์š”์ฒญ
  • ์ƒ‰์ธ์ƒ์„ฑ(Index): ์ „์ฒด ํŽ˜์ด์ง€ ์ƒ‰์ธ ์ƒํƒœ, ์˜ค๋ฅ˜ ๋ชฉ๋ก
  • ๊ฒฝํ—˜(Experience): Core Web Vitals, ๋ชจ๋ฐ”์ผ ์‚ฌ์šฉ์„ฑ
  • ๋งํฌ: ์™ธ๋ถ€ ๋งํฌ, ๋‚ด๋ถ€ ๋งํฌ ํ˜„ํ™ฉ

6. Naver Webmaster Tools ๋“ฑ๋ก ์ „์ฒด ๊ณผ์ •

6-1. ๋„ค์ด๋ฒ„ ์›น๋งˆ์Šคํ„ฐ ๋„๊ตฌ๋ž€?

๋„ค์ด๋ฒ„๋Š” ์ž์ฒด ๊ฒ€์ƒ‰ ์—”์ง„์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. ๊ตญ๋‚ด ์‚ฌ์šฉ์ž๋ฅผ ํƒ€๊ฒŸ์œผ๋กœ ํ•œ๋‹ค๋ฉด ๋„ค์ด๋ฒ„ ๊ฒ€์ƒ‰์—๋„ ๋…ธ์ถœ๋˜์–ด์•ผ ํ•œ๋‹ค. ๋„ค์ด๋ฒ„ ์›น๋งˆ์Šคํ„ฐ ๋„๊ตฌ(searchadvisor.naver.com)์—์„œ ๋“ฑ๋กํ•œ๋‹ค.

6-2. ์‚ฌ์ดํŠธ ๋“ฑ๋ก ๊ณผ์ •

  1. ๋„ค์ด๋ฒ„ ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ ํ›„ ์›น๋งˆ์Šคํ„ฐ ๋„๊ตฌ ์ฝ˜์†” ์ ‘์†
  2. ์‚ฌ์ดํŠธ ์ถ”๊ฐ€ โ†’ URL ์ž…๋ ฅ (์˜ˆ: https://leekh8.github.io)
  3. ์†Œ์œ ํ™•์ธ ๋ฐฉ๋ฒ• ์„ ํƒ

HTML ํŒŒ์ผ ๋ฐฉ์‹:

  1. naverXXXXXXXXXXXXXXXX.html ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ
  2. Gatsby ํ”„๋กœ์ ํŠธ /static ํด๋”์— ๋ณต์‚ฌ
  3. ๋นŒ๋“œ โ†’ ๋ฐฐํฌ โ†’ "์†Œ์œ ํ™•์ธ" ํด๋ฆญ

HTML ํƒœ๊ทธ ๋ฐฉ์‹:

// SEO ์ปดํฌ๋„ŒํŠธ์— ์ถ”๊ฐ€
<meta name="naver-site-verification" content="YOUR_NAVER_CODE" />

6-3. ๋„ค์ด๋ฒ„ sitemap ์ œ์ถœ

  1. ์›น๋งˆ์Šคํ„ฐ ๋„๊ตฌ โ†’ ์š”์ฒญ โ†’ ์‚ฌ์ดํŠธ๋งต ์ œ์ถœ
  2. https://leekh8.github.io/sitemap.xml ์ž…๋ ฅ โ†’ ํ™•์ธ

6-4. RSS ์ œ์ถœ (์„ ํƒ)

๋„ค์ด๋ฒ„ ์›น๋งˆ์Šคํ„ฐ ๋„๊ตฌ๋Š” RSS๋„ ์ง€์›ํ•œ๋‹ค. Gatsby์—์„œ RSS๋ฅผ ์ƒ์„ฑํ•˜๋ ค๋ฉด gatsby-plugin-feed๋ฅผ ์ถ”๊ฐ€๋กœ ์„ค์น˜ํ•˜๋ฉด ๋œ๋‹ค.

npm install gatsby-plugin-feed
// gatsby-config.js
{
  resolve: `gatsby-plugin-feed`,
  options: {
    query: `
      {
        site {
          siteMetadata {
            title
            description
            siteUrl
          }
        }
      }
    `,
    feeds: [
      {
        serialize: ({ query: { site, allMarkdownRemark } }) => {
          return allMarkdownRemark.nodes.map(node => ({
            title: node.frontmatter.title,
            description: node.excerpt,
            date: node.frontmatter.date,
            url: site.siteMetadata.siteUrl + node.fields.slug,
            guid: site.siteMetadata.siteUrl + node.fields.slug,
          }));
        },
        query: `
          {
            allMarkdownRemark(sort: { frontmatter: { date: DESC } }) {
              nodes {
                excerpt
                fields { slug }
                frontmatter {
                  title
                  date
                }
              }
            }
          }
        `,
        output: `/rss.xml`,
        title: `๋‚ด ๋ธ”๋กœ๊ทธ RSS`,
      },
    ],
  },
},

7. Open Graph ๋ฉ”ํƒ€ ํƒœ๊ทธ ์„ค์ •

7-1. Open Graph๋ž€?

Open Graph(OG)๋Š” Facebook์ด ๋งŒ๋“  ํ”„๋กœํ† ์ฝœ๋กœ, ์›น ํŽ˜์ด์ง€๊ฐ€ ์†Œ์…œ ๋ฏธ๋””์–ด์—์„œ ๊ณต์œ ๋  ๋•Œ ์–ด๋–ป๊ฒŒ ํ‘œ์‹œ๋ ์ง€๋ฅผ ์ œ์–ดํ•œ๋‹ค. ์นด์นด์˜คํ†ก, ์Šฌ๋ž™, ํŠธ์œ„ํ„ฐ ๋“ฑ ๋Œ€๋ถ€๋ถ„์˜ ๋ฉ”์‹ ์ €์™€ SNS๊ฐ€ OG ํƒœ๊ทธ๋ฅผ ์ง€์›ํ•œ๋‹ค.

OG ํƒœ๊ทธ๊ฐ€ ์—†์œผ๋ฉด ๊ณต์œ  ์‹œ URL๋งŒ ๋‚˜์˜ค๊ฑฐ๋‚˜ ์ž˜๋ชป๋œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค. OG ํƒœ๊ทธ๊ฐ€ ์ž˜ ์„ค์ •๋ผ ์žˆ์œผ๋ฉด ์ œ๋ชฉ, ์„ค๋ช…, ๋Œ€ํ‘œ ์ด๋ฏธ์ง€๊ฐ€ ์˜ˆ์˜๊ฒŒ ํ‘œ์‹œ๋œ๋‹ค.

7-2. ํ•„์ˆ˜ OG ํƒœ๊ทธ

<!-- ํ•„์ˆ˜ 4๊ฐœ -->
<meta property="og:title" content="ํŽ˜์ด์ง€ ์ œ๋ชฉ" />
<meta property="og:description" content="ํŽ˜์ด์ง€ ์„ค๋ช…" />
<meta property="og:image" content="https://yourdomain.com/og-image.png" />
<meta property="og:url" content="https://yourdomain.com/this-page" />

<!-- ๊ถŒ์žฅ ์ถ”๊ฐ€ ํƒœ๊ทธ -->
<meta property="og:type" content="article" />  <!-- ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ๋Š” article -->
<meta property="og:site_name" content="๋‚ด ๋ธ”๋กœ๊ทธ" />
<meta property="og:locale" content="ko_KR" />

7-3. ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ์šฉ OG ํƒœ๊ทธ ์‹ฌํ™”

// ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ SEO ์ปดํฌ๋„ŒํŠธ
const PostSEO = ({ post }) => (
  <Helmet>
    <meta property="og:type" content="article" />
    <meta property="og:title" content={post.frontmatter.title} />
    <meta property="og:description" content={post.frontmatter.description} />
    <meta property="article:published_time" content={post.frontmatter.date} />
    <meta property="article:modified_time" content={post.frontmatter.update} />
    <meta property="article:author" content="leekh8" />
    {post.frontmatter.tags.map(tag => (
      <meta property="article:tag" content={tag} key={tag} />
    ))}
  </Helmet>
);

7-4. OG ์ด๋ฏธ์ง€ ๊ถŒ์žฅ ์‚ฌ์–‘

  • ํฌ๊ธฐ: 1200 ร— 630px (Facebook ๊ถŒ์žฅ ์‚ฌ์ด์ฆˆ)
  • ๋น„์œจ: 1.91:1
  • ํŒŒ์ผ ํ˜•์‹: JPG, PNG
  • ํŒŒ์ผ ํฌ๊ธฐ: 8MB ์ดํ•˜
  • ํ…์ŠคํŠธ๊ฐ€ ์ด๋ฏธ์ง€ ์ค‘์•™์— ์žˆ์–ด์•ผ ํ•จ (๊ฐ€์žฅ์ž๋ฆฌ๋Š” ์ž˜๋ฆด ์ˆ˜ ์žˆ์Œ)

7-5. Twitter Card ๋ฉ”ํƒ€ ํƒœ๊ทธ

ํŠธ์œ„ํ„ฐ(ํ˜„ X)๋Š” OG ํƒœ๊ทธ์™€ ๋ณ„๋„๋กœ ์ž์ฒด Card ํ˜•์‹์„ ์‚ฌ์šฉํ•œ๋‹ค.

<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@leekh8" />
<meta name="twitter:title" content="ํŽ˜์ด์ง€ ์ œ๋ชฉ" />
<meta name="twitter:description" content="ํŽ˜์ด์ง€ ์„ค๋ช…" />
<meta name="twitter:image" content="https://yourdomain.com/og-image.png" />

summary_large_image๋Š” ํฐ ์ด๋ฏธ์ง€๋ฅผ ํฌํ•จํ•œ ์นด๋“œ ํ˜•ํƒœ๋‹ค. summary๋Š” ์ž‘์€ ์ธ๋„ค์ผ ํ˜•ํƒœ๋‹ค.

7-6. OG ํƒœ๊ทธ ํ™•์ธ ๋„๊ตฌ


8. ๊ตฌ์กฐํ™” ๋ฐ์ดํ„ฐ (JSON-LD) ์„ค์ •

8-1. ๊ตฌ์กฐํ™” ๋ฐ์ดํ„ฐ๋ž€?

๊ตฌ์กฐํ™” ๋ฐ์ดํ„ฐ(Structured Data)๋Š” ๊ฒ€์ƒ‰ ์—”์ง„์ด ํŽ˜์ด์ง€ ๋‚ด์šฉ์„ ๋” ์ž˜ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ํ‘œ์ค€ํ™”๋œ ํ˜•์‹์œผ๋กœ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. Schema.org์—์„œ ์ •์˜ํ•œ ์Šคํ‚ค๋งˆ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, JSON-LD ํ˜•์‹์œผ๋กœ <head> ํƒœ๊ทธ ์•ˆ์— ์‚ฝ์ž…ํ•œ๋‹ค.

๊ตฌ์กฐํ™” ๋ฐ์ดํ„ฐ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์ •ํ•˜๋ฉด ๊ตฌ๊ธ€ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ์—์„œ **๋ฆฌ์น˜ ์Šค๋‹ˆํŽซ(Rich Snippet)**์ด ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ ˆ์‹œํ”ผ ํŽ˜์ด์ง€๋ผ๋ฉด ์š”๋ฆฌ ์‹œ๊ฐ„, ๋ณ„์ ์ด ํ‘œ์‹œ๋˜๊ณ , ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ๋ผ๋ฉด ์ž‘์„ฑ์ž์™€ ๋‚ ์งœ๊ฐ€ ๊ฐ•์กฐ ํ‘œ์‹œ๋  ์ˆ˜ ์žˆ๋‹ค.

8-2. ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ์šฉ JSON-LD

// ๋ธ”๋กœ๊ทธ ํฌ์ŠคํŠธ ๊ตฌ์กฐํ™” ๋ฐ์ดํ„ฐ
const BlogPostSchema = ({ post, siteUrl }) => {
  const schema = {
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    "headline": post.frontmatter.title,
    "description": post.frontmatter.description,
    "image": `${siteUrl}/og-image.png`,
    "datePublished": post.frontmatter.date,
    "dateModified": post.frontmatter.update || post.frontmatter.date,
    "author": {
      "@type": "Person",
      "name": "leekh8",
      "url": siteUrl
    },
    "publisher": {
      "@type": "Organization",
      "name": "leekh8 ๋ธ”๋กœ๊ทธ",
      "logo": {
        "@type": "ImageObject",
        "url": `${siteUrl}/logo.png`
      }
    },
    "mainEntityOfPage": {
      "@type": "WebPage",
      "@id": `${siteUrl}${post.fields.slug}`
    },
    "keywords": post.frontmatter.tags.join(", ")
  };

  return (
    <Helmet>
      <script type="application/ld+json">
        {JSON.stringify(schema)}
      </script>
    </Helmet>
  );
};

8-3. ์›น์‚ฌ์ดํŠธ ์ „์ฒด ์Šคํ‚ค๋งˆ

// ์‚ฌ์ดํŠธ ์ „์ฒด์— ์ ์šฉํ•  WebSite ์Šคํ‚ค๋งˆ
const WebSiteSchema = ({ siteUrl, siteName }) => {
  const schema = {
    "@context": "https://schema.org",
    "@type": "WebSite",
    "name": siteName,
    "url": siteUrl,
    "potentialAction": {
      "@type": "SearchAction",
      "target": `${siteUrl}/?q={search_term_string}`,
      "query-input": "required name=search_term_string"
    }
  };

  return (
    <Helmet>
      <script type="application/ld+json">
        {JSON.stringify(schema)}
      </script>
    </Helmet>
  );
};

8-4. ๊ตฌ์กฐํ™” ๋ฐ์ดํ„ฐ ๊ฒ€์ฆ

๊ตฌ์กฐํ™” ๋ฐ์ดํ„ฐ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์„ค์ •๋๋Š”์ง€ ๊ฒ€์ฆํ•˜๋Š” ๋„๊ตฌ:


9. Lighthouse SEO ์ ์ˆ˜ ํ™•์ธ

9-1. Lighthouse๋ž€?

Lighthouse๋Š” ๊ตฌ๊ธ€์ด ๋งŒ๋“  ์˜คํ”ˆ์†Œ์Šค ์„ฑ๋Šฅ ์ธก์ • ๋„๊ตฌ๋‹ค. Chrome ๊ฐœ๋ฐœ์ž ๋„๊ตฌ์— ๋‚ด์žฅ๋ผ ์žˆ์–ด ๋ณ„๋„ ์„ค์น˜ ์—†์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์Œ ๋‹ค์„ฏ ๊ฐ€์ง€ ํ•ญ๋ชฉ์„ ์ธก์ •ํ•œ๋‹ค:

ํ•ญ๋ชฉ ์„ค๋ช…
Performance ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์†๋„, Core Web Vitals
Accessibility ์ ‘๊ทผ์„ฑ (๋Œ€์ฒด ํ…์ŠคํŠธ, ์ƒ‰์ƒ ๋Œ€๋น„ ๋“ฑ)
Best Practices ๋ณด์•ˆ, ์ตœ์‹  API ์‚ฌ์šฉ ์—ฌ๋ถ€
SEO ๊ฒ€์ƒ‰ ์—”์ง„ ์ตœ์ ํ™” ์„ค์ •
PWA Progressive Web App ์ค€์ˆ˜ ์—ฌ๋ถ€

9-2. Lighthouse ์‹คํ–‰ ๋ฐฉ๋ฒ•

Chrome ๊ฐœ๋ฐœ์ž ๋„๊ตฌ ์‚ฌ์šฉ:

  1. ๋ถ„์„ํ•˜๋ ค๋Š” ํŽ˜์ด์ง€ ์—ด๊ธฐ
  2. F12 (๊ฐœ๋ฐœ์ž ๋„๊ตฌ ์—ด๊ธฐ)
  3. "Lighthouse" ํƒญ ์„ ํƒ
  4. ๋ถ„์„ ์นดํ…Œ๊ณ ๋ฆฌ ์„ ํƒ ํ›„ "Analyze page load" ํด๋ฆญ

CLI ์‚ฌ์šฉ:

npm install -g lighthouse
lighthouse https://leekh8.github.io --output html --output-path ./report.html

9-3. SEO ์ ์ˆ˜ ์˜ฌ๋ฆฌ๋Š” ์ฒดํฌ๋ฆฌ์ŠคํŠธ

Lighthouse SEO ๊ฒ€์‚ฌ ํ•ญ๋ชฉ:

  • <title> ํƒœ๊ทธ ์กด์žฌ ์—ฌ๋ถ€
  • <meta name="description"> ํƒœ๊ทธ ์กด์žฌ ์—ฌ๋ถ€
  • ๋ชจ๋“  ๋งํฌ์— ์„ค๋ช… ํ…์ŠคํŠธ ์กด์žฌ ์—ฌ๋ถ€
  • robots.txt ํŒŒ์ผ ์œ ํšจ์„ฑ
  • ์ด๋ฏธ์ง€์— alt ์†์„ฑ ์กด์žฌ ์—ฌ๋ถ€
  • ํŽ˜์ด์ง€๊ฐ€ ํฌ๋กค๋ง ๊ฐ€๋Šฅํ•œ์ง€ ์—ฌ๋ถ€
  • hreflang ํƒœ๊ทธ (๋‹ค๊ตญ์–ด ์ง€์› ์‹œ)
  • canonical URL ์„ค์ • ์—ฌ๋ถ€

100์ ์— ๊ฐ€๊นŒ์šธ์ˆ˜๋ก SEO ๊ธฐ์ดˆ๊ฐ€ ์ž˜ ๊ฐ–์ถฐ์ง„ ๊ฒƒ์ด๋‹ค.


10. ๊ตฌ๊ธ€ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๋…ธ์ถœ๊นŒ์ง€ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„

10-1. ์ธ๋ฑ์‹ฑ ํƒ€์ž„๋ผ์ธ

GSC์— ์‚ฌ์ดํŠธ๋ฅผ ๋“ฑ๋กํ•˜๊ณ  sitemap์„ ์ œ์ถœํ•œ๋‹ค๊ณ  ํ•ด์„œ ๋ฐ”๋กœ ๊ตฌ๊ธ€์— ๋…ธ์ถœ๋˜์ง€๋Š” ์•Š๋Š”๋‹ค. ์ผ๋ฐ˜์ ์ธ ํƒ€์ž„๋ผ์ธ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๊ธฐ๊ฐ„ ์ƒํƒœ
1-3์ผ Googlebot์ด ํฌ๋กค๋ง ์‹œ์ž‘
1-2์ฃผ ์ฃผ์š” ํŽ˜์ด์ง€ ์ƒ‰์ธ ์‹œ์ž‘
1-3๊ฐœ์›” ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ์ˆœ์œ„ ์•ˆ์ •ํ™”
3-6๊ฐœ์›” ๊พธ์ค€ํžˆ ๊ฒŒ์‹œํ•  ๊ฒฝ์šฐ ๋…ธ์ถœ ์ฆ๊ฐ€

์ƒˆ ์‚ฌ์ดํŠธ๋Š” "๊ตฌ๊ธ€์ด ์‹ ๋ขฐ๋ฅผ ์Œ“๋Š” ์‹œ๊ฐ„(Sandbox period)"์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์•Œ๋ ค์ ธ ์žˆ๋‹ค. ํŠนํžˆ ์ฒ˜์Œ 3๊ฐœ์›”์€ ๋…ธ์ถœ์ด ์ ๋”๋ผ๋„ ๊พธ์ค€ํžˆ ์ฝ˜ํ…์ธ ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•˜๋‹ค.

10-2. ์ƒ‰์ธ์ด ์•ˆ ๋  ๋•Œ ํ™•์ธ์‚ฌํ•ญ

GSC > URL ๊ฒ€์‚ฌ ๋„๊ตฌ ํ™œ์šฉ:

  1. GSC ์ขŒ์ธก ์ƒ๋‹จ ๊ฒ€์ƒ‰๋ฐ”์— ํ™•์ธํ•˜๊ณ  ์‹ถ์€ URL ์ž…๋ ฅ
  2. "URL์ด Google์— ๋“ฑ๋ก๋˜์–ด ์žˆ์ง€ ์•Š์Œ" โ†’ ์ƒ‰์ธ ์•ˆ ๋จ
  3. "์ƒ‰์ธ ์ƒ์„ฑ ์š”์ฒญ" ๋ฒ„ํŠผ ํด๋ฆญ

์ƒ‰์ธ ์š”์ฒญ ํ›„ ์ˆ˜์ผ ๋‚ด์— ์ฒ˜๋ฆฌ๋œ๋‹ค. ํ•˜์ง€๋งŒ ์š”์ฒญ์ด ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๋…ธ์ถœ์„ ๋ณด์žฅํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค.

์ž์ฃผ ํ™•์ธํ•ด์•ผ ํ•  ์ƒ‰์ธ ์‹คํŒจ ์›์ธ:

  • robots.txt์—์„œ ํ•ด๋‹น URL์„ ์ฐจ๋‹จํ•˜๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ
  • <meta name="robots" content="noindex"> ํƒœ๊ทธ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ
  • ํŽ˜์ด์ง€ ๋‚ด์šฉ์ด ๋„ˆ๋ฌด ์–‡๊ฑฐ๋‚˜ ์ค‘๋ณต ์ฝ˜ํ…์ธ ์ธ ๊ฒฝ์šฐ
  • ์„œ๋ฒ„ ์˜ค๋ฅ˜(5xx), ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ์˜ค๋ฅ˜(3xx)๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ
  • ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์†๋„๊ฐ€ ๋„ˆ๋ฌด ๋А๋ฆฐ ๊ฒฝ์šฐ

11. ์ƒ‰์ธ ์š”์ฒญ ๋ฐฉ๋ฒ• โ€” URL ๊ฒ€์‚ฌ ๋„๊ตฌ ํ™œ์šฉ

11-1. ์ƒˆ ๊ธ€ ๋ฐœํ–‰ ํ›„ ์ฆ‰์‹œ ์ƒ‰์ธ ์š”์ฒญ

์ƒˆ ํฌ์ŠคํŠธ๋ฅผ ๋ฐœํ–‰ํ•˜๋ฉด Googlebot์ด ๋ฐœ๊ฒฌํ•˜๊ธฐ๊นŒ์ง€ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฐ๋‹ค. GSC์˜ URL ๊ฒ€์‚ฌ ๋„๊ตฌ๋กœ ์ง์ ‘ ์ƒ‰์ธ์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. GSC ์ ‘์† โ†’ ์ƒ๋‹จ ๊ฒ€์ƒ‰๋ฐ”์— ์ƒˆ ํฌ์ŠคํŠธ URL ์ž…๋ ฅ
  2. "URL์ด Google์— ๋“ฑ๋ก๋˜์–ด ์žˆ์ง€ ์•Š์Œ" ๋˜๋Š” ํ˜„์žฌ ์ƒ‰์ธ ์ƒํƒœ ํ‘œ์‹œ
  3. "์ƒ‰์ธ ์ƒ์„ฑ ์š”์ฒญ" ๋ฒ„ํŠผ ํด๋ฆญ
  4. "ํ…Œ์ŠคํŠธ ๋ผ์ด๋ธŒ URL" โ†’ ํŽ˜์ด์ง€๊ฐ€ ์ •์ƒ ๋ Œ๋”๋ง๋˜๋Š”์ง€ ํ™•์ธ
  5. "์ƒ‰์ธ ์ƒ์„ฑ ์š”์ฒญ" ์ตœ์ข… ํ™•์ธ

ํ•˜๋ฃจ์— ์ƒ‰์ธ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋Š” ํšŸ์ˆ˜์— ์ œํ•œ์ด ์žˆ๋‹ค. ์ •ํ™•ํ•œ ์ˆ˜์น˜๋Š” ๊ณต๊ฐœ๋˜์ง€ ์•Š์•˜์ง€๋งŒ ํ•˜๋ฃจ 10-15ํšŒ ์ •๋„๊ฐ€ ์ผ๋ฐ˜์ ์œผ๋กœ ์–ธ๊ธ‰๋œ๋‹ค.

11-2. Bing Webmaster Tools๋„ ํ•จ๊ป˜

๋งˆ์ดํฌ๋กœ์†Œํ”„ํŠธ Bing๋„ ๊ตญ๋‚ด์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ์žˆ๋‹ค. Bing Webmaster Tools์—๋„ ์‚ฌ์ดํŠธ๋ฅผ ๋“ฑ๋กํ•ด ๋‘๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. GSC์™€ ์—ฐ๋™ ๊ธฐ๋Šฅ์ด ์žˆ์–ด GSC ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋Œ€๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.


12. ์ž์ฃผ ํ•˜๋Š” SEO ์‹ค์ˆ˜

12-1. <title> ํƒœ๊ทธ ์ค‘๋ณต

๋ชจ๋“  ํŽ˜์ด์ง€๊ฐ€ ๋™์ผํ•œ <title> ํƒœ๊ทธ๋ฅผ ๊ฐ€์ง€๋ฉด ๊ตฌ๊ธ€์ด ํŽ˜์ด์ง€๋ฅผ ๊ตฌ๋ถ„ํ•˜์ง€ ๋ชปํ•œ๋‹ค. ๊ฐ ํŽ˜์ด์ง€๋ณ„๋กœ ๊ณ ์œ ํ•œ ์ œ๋ชฉ์„ ์„ค์ •ํ•ด์•ผ ํ•œ๋‹ค.

// ์ž˜๋ชป๋œ ์˜ˆ: ๋ชจ๋“  ํŽ˜์ด์ง€๊ฐ€ ๊ฐ™์€ ์ œ๋ชฉ
<title>๋‚ด ๋ธ”๋กœ๊ทธ</title>

// ์˜ฌ๋ฐ”๋ฅธ ์˜ˆ: ํŽ˜์ด์ง€๋ณ„ ๊ณ ์œ  ์ œ๋ชฉ
<title>SQL Basic - 1. ์†Œ๊ฐœ ๋ฐ ๊ธฐ๋ณธ ๊ฐœ๋… | ๋‚ด ๋ธ”๋กœ๊ทธ</title>

12-2. <meta name="description"> ์—†๊ฑฐ๋‚˜ ์ค‘๋ณต

description์ด ์—†์œผ๋ฉด ๊ตฌ๊ธ€์ด ์ž„์˜๋กœ ๋ณธ๋ฌธ์—์„œ ๋ฐœ์ทŒํ•ด ํ‘œ์‹œํ•œ๋‹ค. ์ด ๊ฒฝ์šฐ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๊ฐ€ ์–ด์ƒ‰ํ•˜๊ฒŒ ๋‚˜ํƒ€๋‚  ์ˆ˜ ์žˆ๋‹ค. ํŽ˜์ด์ง€๋งˆ๋‹ค ๊ณ ์œ ํ•œ description์„ ์ž‘์„ฑํ•˜์ž.

  • ๊ถŒ์žฅ ๊ธธ์ด: 120-160์ž (๋ชจ๋ฐ”์ผ ๊ธฐ์ค€ ~120์ž)
  • ๋„ˆ๋ฌด ์งง์•„๋„ (50์ž ๋ฏธ๋งŒ), ๋„ˆ๋ฌด ๊ธธ์–ด๋„ ์ž˜๋ฆด ์ˆ˜ ์žˆ์–ด ์ข‹์ง€ ์•Š๋‹ค

12-3. ์ด๋ฏธ์ง€ alt ์†์„ฑ ๋ˆ„๋ฝ

<!-- ๋‚˜์œ ์˜ˆ -->
<img src="diagram.png" />

<!-- ์ข‹์€ ์˜ˆ -->
<img src="diagram.png" alt="SQL SELECT ๋ฌธ ์‹คํ–‰ ํ๋ฆ„๋„" />

alt ์†์„ฑ์€ ์ ‘๊ทผ์„ฑ์„ ์œ„ํ•œ ๊ฒƒ์ด๊ธฐ๋„ ํ•˜์ง€๋งŒ, ๊ตฌ๊ธ€ ์ด๋ฏธ์ง€ ๊ฒ€์ƒ‰์—์„œ๋„ ํ™œ์šฉ๋œ๋‹ค.

12-4. noindex ํƒœ๊ทธ ์‹ค์ˆ˜

๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•˜๋Š” noindex ํƒœ๊ทธ๋ฅผ ํ”„๋กœ๋•์…˜์— ๊ทธ๋Œ€๋กœ ์˜ฌ๋ฆฌ๋Š” ์‹ค์ˆ˜๊ฐ€ ์ข…์ข… ๋ฐœ์ƒํ•œ๋‹ค.

<!-- ์ด ํƒœ๊ทธ๊ฐ€ ์žˆ์œผ๋ฉด ๊ตฌ๊ธ€์ด ์ƒ‰์ธํ•˜์ง€ ์•Š์Œ -->
<meta name="robots" content="noindex" />

GSC์—์„œ ์ƒ‰์ธ์ด ์•ˆ ๋œ๋‹ค๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋‚˜์˜ค๋ฉด ์ด ํƒœ๊ทธ๋ฅผ ํ™•์ธํ•ด ๋ณด์ž.

12-5. canonical URL ๋ฏธ์„ค์ •

๊ฐ™์€ ๋‚ด์šฉ์ด ์—ฌ๋Ÿฌ URL๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•  ๋•Œ(์˜ˆ: http/https, www ์œ ๋ฌด, ํ›„ํ–‰ ์Šฌ๋ž˜์‹œ ์œ ๋ฌด) ๊ตฌ๊ธ€์ด ์–ด๋–ค URL์ด ๋Œ€ํ‘œ์ธ์ง€ ๋ชจ๋ฅผ ์ˆ˜ ์žˆ๋‹ค.

<!-- ๊ฐ ํŽ˜์ด์ง€์— canonical URL ๋ช…์‹œ -->
<link rel="canonical" href="https://leekh8.github.io/posts/my-post/" />

12-6. ํŽ˜์ด์ง€ ์†๋„ ๋ฌด์‹œ

๊ตฌ๊ธ€์€ ํŽ˜์ด์ง€ ๋กœ๋”ฉ ์†๋„๋ฅผ ๋žญํ‚น ์š”์†Œ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. Gatsby๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ตœ์ ํ™”๊ฐ€ ์ž˜ ๋ผ ์žˆ์ง€๋งŒ, ์™ธ๋ถ€ ํฐํŠธ, ๊ณผ๋„ํ•œ ์ด๋ฏธ์ง€ ๋“ฑ์ด ์„ฑ๋Šฅ์„ ๋–จ์–ด๋œจ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

Lighthouse Performance ์ ์ˆ˜๊ฐ€ 90์  ๋ฏธ๋งŒ์ด๋ผ๋ฉด ๊ฐœ์„ ์ด ํ•„์š”ํ•˜๋‹ค. gatsby-plugin-image๋กœ ์ด๋ฏธ์ง€๋ฅผ ์ตœ์ ํ™”ํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋„ ์ ์ˆ˜๊ฐ€ ํฌ๊ฒŒ ์˜ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค.

12-7. ๋ชจ๋ฐ”์ผ ์ตœ์ ํ™” ๋ฏธํก

๊ตฌ๊ธ€์€ **๋ชจ๋ฐ”์ผ ์šฐ์„  ์ƒ‰์ธ(Mobile-first Indexing)**์„ ์ ์šฉํ•œ๋‹ค. ์ฆ‰, ๋ชจ๋ฐ”์ผ ๋ฒ„์ „์˜ ์ฝ˜ํ…์ธ ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ƒ‰์ธํ•œ๋‹ค. ๋ฐ˜์‘ํ˜• ๋””์ž์ธ์ด ์ ์šฉ๋ผ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜์ž.

<!-- viewport ๋ฉ”ํƒ€ ํƒœ๊ทธ ํ•„์ˆ˜ -->
<meta name="viewport" content="width=device-width, initial-scale=1" />

๋งˆ๋ฌด๋ฆฌ

SEO๋Š” ๋‹จ๊ธฐ๊ฐ„์— ํšจ๊ณผ๊ฐ€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๋Š”๋‹ค. ์„ค์ •์„ ์™„๋ฃŒํ•œ ํ›„ ๊พธ์ค€ํžˆ ์ฝ˜ํ…์ธ ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด์„œ GSC ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋ฉฐ ๊ฐœ์„ ํ•ด ๋‚˜๊ฐ€๋Š” ๊ณผ์ •์ด๋‹ค.

์ฒดํฌ๋ฆฌ์ŠคํŠธ ์ •๋ฆฌ:

  • gatsby-plugin-sitemap ์„ค์ • ๋ฐ sitemap.xml ์ œ์ถœ
  • gatsby-plugin-robots-txt ์„ค์ • ๋ฐ robots.txt ํ™•์ธ
  • ๊ฐ ํŽ˜์ด์ง€์— ๊ณ ์œ ํ•œ <title>, <meta description> ์„ค์ •
  • Open Graph ํƒœ๊ทธ ์„ค์ • (og:title, og:description, og:image, og:url)
  • Google Search Console ๋“ฑ๋ก ๋ฐ sitemap ์ œ์ถœ
  • Naver Webmaster Tools ๋“ฑ๋ก ๋ฐ sitemap ์ œ์ถœ
  • ๊ตฌ์กฐํ™” ๋ฐ์ดํ„ฐ (JSON-LD) ์ถ”๊ฐ€
  • ์ด๋ฏธ์ง€ alt ์†์„ฑ ํ™•์ธ
  • Lighthouse SEO ์ ์ˆ˜ 90์  ์ด์ƒ ๋‹ฌ์„ฑ
  • ๋ชจ๋ฐ”์ผ ๋ฐ˜์‘ํ˜• ํ™•์ธ

ํ•œ ๋ฒˆ ์„ธํŒ…ํ•ด ๋‘๋ฉด ์ดํ›„์—๋Š” ์ข‹์€ ์ฝ˜ํ…์ธ ๋ฅผ ๊พธ์ค€ํžˆ ์“ฐ๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ๊ฐ•๋ ฅํ•œ SEO ์ „๋žต์ด๋‹ค.


@leekh8
๋ณด์•ˆ, ์›น ๊ฐœ๋ฐœ, Python์„ ๋‹ค๋ฃจ๋Š” ๊ธฐ์ˆ  ๋ธ”๋กœ๊ทธ