SEO 적용기

SangHyeon Lee·2025년 11월 25일

시작하며

고도화 작업 중 하나로, SEO 작업을 꼭 해보고 싶었다.

인턴 생활 때도 사이트맵이 어쩌구 하며 FE 팀원 분이 작업하실 때 무슨 소린지 못 알아들었던 것과 동아리 홈페이지 유지관리 팀에서 OpenGraph 처리 작업을 하려다 못했던 것이 아쉬웠기 때문이다.

우리 서비스는 딱히 SEO가 중요한 서비스는 아니지만, 어쨌든 완성되어 성공적으로 배포했기에 할 수 있는 한 SEO 최적화를 진행하고자 했다.

적용기

Gemini에게 물어보니, 다음의 작업들이 필요했다.

Metadata, OpenGraph, SiteMap, Robots.txt

Metadata 처리하기

Next.js를 사용하고 있었기 때문에 문서를 보면서 진행했는데,

당시 page.tsx가 모두 RCC였기 때문에 동적으로 처리하기 애매하여 정적으로 처리하게 되었다.
(아직 SSR 전환 전이었다.)

사실상 Next.js에서 기본적으로 지원하는 방식이 있어서 native로 처리하는 것보다 간단했다.

export const metadata: Metadata = {
  title: "타이틀",
  description: "설명",
  keywords: ["키워드1","키워드2",...],
};

타입이 정의되어있기 때문에, 필요한 것들을 채워주면 되었다.

OpenGraph

사실 제일 눈에 띄는 변화라면 OG라고 할 수 있다.

찾아보니, facebook과 twitter 크게 두 가지에 대응되는 방식이 있었다.

각각에 맞춤으로 만들기보다 가성비 좋게 처리하기 위해 공통으로 쓰이는 것들만 처리하기로 했다.

(참고로, Next에서 알아서 각 영역에 특화된 내용들을 만들어 주기도 한다고 함)

항목들은 아래와 같다.

  • og:title
  • og:description
  • og:image
  • og:url
  • og:type


Next에서는 Metadata와 OG를 한번에 설명하고 있었는데, 위 항목을 보면 알겠지만 Metadata에 작성된 부분과 일치하는 것이 많다.

title, description은 Next가 빌드 시 OG 관련 정보로 처리해준다고 한다.

남은 url과 type은 아래와 같이 Metadata에 입력하면 된다.

openGraph: {
    url: "페이지 url",
    type: "website",
  },
};

마지막 남은 OG image는 opengraph-image.png를 app폴더 바로 아래에 위치시키면 됐다.

빌드 시 아래와 같이 된다.

<meta property="og:title" content="모티모 | 그룹 기반 목표 관리 서비스"/>
<meta property="og:description" content="그룹 매칭을 통해 목표를 관리해요!"/>
<meta property="og:url" content="https://6d93a4b5a919.ngrok-free.app"/>
<meta property="og:image:type" content="image/png"/>
<meta property="og:image:width" content="1600"/>
<meta property="og:image:height" content="630"/>
<meta property="og:image" content="https://6d93a4b5a919.ngrok-free.app/opengraph-image.png?23ecf2e2dc069f9f"/>
<meta property="og:type" content="website"/>

참고로, 개발환경에서 테스트하기 위해 ngrok을 사용했고, facebook의 og 테스트 사이트에서 확인하며 개발을 진행했다.

SiteMap

사이트맵은, 구글 크롤러가 우리 사이트의 각 페이지들 정보를 가져갈 수 있도록 하는 것이다.

우리 서비스는 웹앱에 가깝기 때문에, 특히 랜딩 페이지나 소개 페이지도 없기 때문에 사이트맵을 적용하지 않으려 했다.

개인 정보만으로 이뤄진 우리 서비스는 외부에 공개되는 정보인 SiteMap을 갖는 것이 안 좋을 수 있는 것이다.


그러나, 로그인이 들어가는 Onboarding 페이지는 공개하기로 했다.

사용자가 이를 통해 어떤 서비스인지 알 수 있고 (서비스 소개 문구가 적힌 이미지가 사용되고 있었다), 이 페이지조차 처리하지 않으면 외부로 공개하지 못할 것 같았기 때문이다.


역시 Next.js에서 지원해주는 기능을 사용하면 간편했고, 처리할 페이지도 하나뿐이라 아래와 같이 간단한 코드로 해결했다.

// app/sitemap.ts
import type { MetadataRoute } from "next";

export default function sitemap(): MetadataRoute.Sitemap {
  return [
    {
      url: `서비스URL/onboarding`,
      lastModified: new Date(),
      changeFrequency: "always", // 사실 never로 해도 상관은 없을 듯.
      priority: 1,
    },
  ];
}

SiteMap은 원래 XML파일을 제공해야 하는데, Next에서 위 코드를 보고 빌드 시 해당 파일을 제작하는 것으로 보였다.

Robots.txt

이는 SiteMap과 반대로, 크롤러가 들어오지 못하게 하는 작업이다.

사실, 여기서 처리해도 무시하고 들어오는 경우도 있긴 하지만, 최소한의 처리라고 보면 될 것 간다.

이 부분을 대충 처리한다면, 불필요한 요청이 많아져 비용적으로 손해가 클 것이다.


우리 서비스에선 onboarding만 허용하기로 했으므로 코드는 아래와 같았다.

// robots.ts

import type { MetadataRoute } from "next";

export default function robots(): MetadataRoute.Robots {
  return {
    rules: {
      userAgent: "*",
      allow: "/onboarding",
      disallow: [
        "/adding-goal/",
        "/details/",
        "/feed/",
        "/group/",
        "/mypage/",
        "/notification/",
        "/api/",
      ],
    },
    sitemap: `서비스URL/sitemap.xml`,
  };
}

마치며

직접 적용해보기 전에는 어렵게만 느껴졌는데, 막상 해보니 생각보다 작업량도 많지 않고 부담이 없었다.

위 과정 이외에도, SEO최적화에 좋은 것은 Semantic HTML, 사이트 로딩 속도 등이 있는데, 이러한 부분은 다른 영역이라 생각해 담지 않았다.


이 경험을 통해 왜 웹앱이 많지 않은지 느꼈다.

결국 검색이 잘 되어 신규 이용자를 늘리는 것이 신생 서비스의 최고 목표인데, 웹앱의 경우 SEO를 통해 사용자를 늘리기는 어려운 것이다.

외부로 드러낼 정보 대신, 사용자 개인 정보를 활용하는 것이 대부분인 웹앱은 시작부터 단점을 안고 가는 것이나 다름 없다.


그러나, 이번에 사이트맵 적용 대상이었던 온보딩 페이지라거나, SSR 적용되었다면 고려했을 그룹 채팅 별 동적 OG 및 Metadata 등 SSR을 통해 충분히 최적화 가능한 부분이 있기 때문에 SSR의 장점을 확인할 수 있었다.

profile
회고할 가치가 있는 개발을 하자

0개의 댓글