Post

DEKK의 SEO 최적화

DEKK의 SEO 최적화 과정과 결과에 대한 기술 블로그입니다.

DEKK의 SEO 최적화

📌 개요

Technical SEO 도입을 고민하게 된 배경과 도입하며 고려한 것에 관해서 기술합니다.


🤔 Technical SEO 도입을 고민하게 된 배경

‘서비스를 만들었지만, 유입이 없으면 유령 서비스가 아닐까?’ 라는 고민에서 시작되었습니다.

마케팅을 잘하면 잠깐의 유입은 있겠지만 결국 마케팅은 단발성 유입 확보에 불과할 뿐 서비스의 지속적인 원동력이라고 생각하지 않았습니다.

그래서 ‘어떻게 하면 자연스럽게 사용자가 우리 서비스를 거부감 없이 접근할 수 있을까’ 라는 고민의 답은 SEO 최적화라고 생각했습니다.

사용자의 피드백은 항상 냉정하다고 생각하여 “원하지 않거나 필요로 하지 않으면 사용하지 않는다” 라는 접근법을 항상 서비스 차원에서 염두하고 기획을 합니다.

하지만 항상 생각만 했지, 실행해 본 경험은 없어 제 생각이 확실한지 시험해 볼 수 있는 좋은 기회라고 생각되어 진행하게 되었습니다.


✅ Technical SEO 도입

크롤링 원리 및 설명

여러 검색엔진 플랫폼에서는 단순 HTTP 요청을 받아 번들 파일을 분석하기에 앞서 robots.txt로 이 서비스에서 허용하는 라우트(route)를 확인 한 후, 정보 수집을 시작합니다.

루트(root; 보통 메인 페이지) 페이지에서 시작하여 소스코드에 포함된 주소를 타고가며 정보를 수집하게 되는데, 이런 과정이 한 서비스에만 집중할 수 없고 어느 주기로 업데이트가 발생하는지 봇은 판단할 수 없어 크롤링 주기가 일정하지 않게됩니다.

만약 크롤링 주기가 일정하지 않다면 서비스에서는 업데이트가 활발하게 발생하여 꾸준한 검색어 등록이 되어야하는데 봇이 서비스의 업데이트 주기를 확인하기 까지 시간이 다소 소모되게 됩니다. 이를 방지하고자 sitemap.xml을 서비스 차원에서 제공하여 ‘우리 서비스에서는 이 도메인이 자주 업데이트 되니까 자주 업데이트를 반영해줘’ 라고 우선순위(priority)와 변경 주기를 제공하여 봇이 서비스의 구조를 더 잘 이해할 수 있게 도와줍니다.

이제 본격적으로 봇이 HTML 문서를 파싱하는 단계입니다. 봇은 크게 head 태그와 body 태그 두 가지를 분석하게 되는데, 우선 head 태그를 먼저 확인하게 되며 해당 문서가 어떤 문서인지 간략한 설명을 받게 되고, 이 문서의 주제가 어떤 문서인지 판단 후, body에서 그 판단을 검증하게 됩니다.

이후 핵심 문서를 분석하여 서비스가 등록된 검색엔진에서 검색을 하게 되면 사용자에게 추천되는 시스템으로 설계되어 있습니다.

💡 봇은 Top-Down 방식으로 위에서 아래로 HTML 문서를 분석합니다.

방법 1: robots.txt 도입

1
2
3
4
5
User-Agent: *
Allow: /
Disallow: /me

Sitemap: https://dekk.co.kr/sitemap.xml

User-Agent로 모든 검색엔진을 허용하여 최대한 많은 검색엔진 봇이 정보를 수집할 수 있게 가능성을 열어줬습니다.

Allow로 루트 라우트만 허용하고 있지만, Disallow 처럼 명시적 금지만 없으면 암묵적으로 허용으로 간주해 루트 라우트만 명시해줬습니다.

마지막으로 봇이 처음 크롤링을 시작했을 때 robots만 확인하게 되는데 Sitemap의 존재를 명시하여 다음 스탭을 조금 더 원활하게 만들어줬습니다. 하지만 검색엔진에 서비스를 등록할 때 사이트맵을 직접 추가할 수 있지만, 다른 검색엔진 서비스에서도 크롤링될 때 조금 더 용이한 수집을 돕기 위해서 robots에 명시했습니다.

방법 2: sitemap.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
	<url>
		<loc>https://dekk.co.kr/</loc>
		<changefreq>daily</changefreq>
		<priority>1</priority>
	</url>
	<url>
		<loc>https://dekk.co.kr/main</loc>
		<changefreq>daily</changefreq>
		<priority>1</priority>
	</url>
	<url>
		<loc>https://dekk.co.kr/deck</loc>
		<changefreq>daily</changefreq>
		<priority>0.9</priority>
	</url>
	<url>
		<loc>https://dekk.co.kr/post</loc>
		<changefreq>weekly</changefreq>
		<priority>0.7</priority>
	</url>
	<url>
		<loc>https://dekk.co.kr/login</loc>
		<changefreq>monthly</changefreq>
		<priority>0.4</priority>
	</url>
	<url>
		<loc>https://dekk.co.kr/join</loc>
		<changefreq>monthly</changefreq>
		<priority>0.4</priority>
	</url>
</urlset>

사이트맵을 제시하며 위치(location), 변경 빈도(changefreq;Change Frequency), 우선 순위(priority)를 작성하여 서비스에서 제일 많이 노출하고 싶은 부분을 명시해줍니다.

방법 3: metadata 명시

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
export const metadata: Metadata = {
  title: "DEKK",
  applicationName: "DEKK",
  description: "나에게 꼭 맞는 맞춤 핏을 탐색하고 수집하세요!",
  metadataBase: new URL(SITE_URL),

  alternates: {
    canonical: "/main",
  },

  icons: {
    icon: [{ url: "/icon.png", type: "image/png" }],
    apple: [{ url: "/apple-icon.png", type: "image/png" }],
    shortcut: [{ url: "/favicon.ico", type: "image/x-icon" }],
  },

  openGraph: {
    title: "DEKK",
    description: "나에게 꼭 맞는 맞춤 핏을 탐색하고 수집하세요!",
    siteName: "DEKK",
    type: "website",
    images: [
      {
        url: "/og.jpg",
      },
    ],
  },

  twitter: {
    card: "summary_large_image",
    title: "DEKK",
    description: "나에게 꼭 맞는 맞춤 핏을 탐색하고 수집하세요!",
    images: ["/og.jpg"],
  },
};

nextjs에서 작성된 metadata의 모습입니다.

metadata는 단순 페이지의 설명만 작성되는게 아닌 아이콘을 등록해 서비스의 정체성을 표현할 수도 있고, 사용자가 불특정 다수에게 공유할 때 오픈 그래프(og)를 이용해 대략적인 서비스의 내용을 이미지로 설명하고, 크롤 봇이 어떤 정보를 수집할지에 대한 판단을 1차적으로 할 수 있게 도와줍니다.

방법 4: aria 속성 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<Button
	aria-label="필터 적용"
	className="h-9 w-9 p-0"
	type="submit"
	variant="primary"
>
	<Search size={16} />
</Button>

<Link
	aria-label="필터 초기화"
	className="inline-flex h-9 w-9 items-center justify-center rounded-sm border border-border bg-card transition-colors hover:bg-muted"
	href="/cards"
>
	<RotateCcw size={16} />
</Link>

aria 속성은 W3C의 표준 기술로 보통 ‘웹 접근성’ 기술에 들어갑니다.

보통의 경우에는 ‘스크린 리더’ 라는 기능을 통해 해당 요소(element; 버튼, 링크 등)가 어떤 역할을 수행하는지 명시적으로 알려주는 역할을 합니다.

만약 div태그를 버튼으로 사용하는 경우 aria-role="button" 으로 명시해주는 등 sementic tag 규칙을 지켜줘야 SEO 점수가 더 높게 나올 수 있습니다.

📊 결과 & 성능

image

  • SEO 최적화 100점



image

  • 구글 검색 최상단 노출

🎓 배운 점

  • 검색 노출이 막연하게 쉬운 줄 알고 시도했지만 생각보다 신경쓸게 많아 실제로 적용해보며 어떤 상황에서 검색어 노출이 될 수 있는지, 어떤 페이지가 노출되면 안되는지 판단할 수 있게 되었고 이 플로우를 이해하며 조금 더 프로덕트 관점에서 생각할 수 있게 만들어줘 좋은 경험이 됐습니다.

🔗 참고 자료

This post is licensed under CC BY 4.0 by the author.