검색 엔진에서 '네이버'나 '카카오'를 검색하면 체계적으로 정리된 목차가 나타나는데, 정작 우리 서비스를 검색하면 그런 구조화된 정보가 보이지 않더라고요. 이게 단순히 보기 좋은 문제가 아니라, 사용자 경험과 직결되는 부분이라 개선이 필요했습니다.
문제점
처음 문제를 발견했을 때 상황입니다. 검색 결과가 심플하게 나오긴 하는데, 사용자 입장에서는 우리 사이트가 어떤 서비스를 제공하는지, 어떤 콘텐츠가 있는지 한눈에 파악하기 어려웠어요.
반면 네이버나 카카오 같은 경우를 보면 아래와 같이 사이트에 접속하기 전에 체계적으로 파악할 수 있어요.
해결 과정 : 스키마 마크업 적용하기
이 문제를 해결하는 핵심은 스키마 마크업(Schema Markup)입니다. 검색 엔진에게 "우리 페이지의 이 부분은 이런 의미야"라고 명확히 알려주는 거예요.
1단계: 스키마 타입 선택하기
먼저 Schema.org에서 우리 서비스에 맞는 타입을 찾아야 했어요. 엘리스는 교육 플랫폼이니까 EducationalOrganization 타입이 딱 맞았습니다.
스키마 타입을 고를 때는 서비스의 본질을 생각해보면 좋아요. 쇼핑몰이면 Organization이나 Store, 뉴스 사이트면 NewsArticle, 레시피 사이트면 Recipe 이런 식으로요.
2단계: 타입 안정성 확보하기
실제 코드를 작성할 때는 schema-dts 라이브러리를 사용했어요. 이게 정말 편한 게, Schema.org의 모든 타입을 TypeScript로 정의해놔서 자동완성도 되고 타입 체크도 할 수 있거든요.
npm install schema-dts
3단계: JSON-LD 방식으로 구현하기
스키마 마크업을 추가하는 방법은 크게 세 가지가 있어요:
- JSON-LD: 가장 권장되는 방식이고, 코드도 깔끔합니다
- Microdata: HTML 태그에 직접 속성을 추가하는 방식
- RDFa: 좀 더 복잡한 시맨틱 마크업
저는 JSON-LD를 선택했어요. Next.js의 layout.tsx에 이렇게 추가했습니다:
import Script from 'next/script';
import { WithContext, EducationalOrganization } from 'schema-dts';
const BASE_URL = 'https://elice.io';
const jsonLd: WithContext<EducationalOrganization> = {
'@type': 'EducationalOrganization',
'@context': 'https://schema.org',
'@id': 'https://elice.io',
name: '엘리스 - 올인원 디지털 교육 플랫폼',
keywords: ['엘리스', 'elice', '올인원', '디지털', '교육', '플랫폼'],
address: '서울특별시 강남구 테헤란로 427, 4층',
image: `${BASE_URL}/images/default_seo.png`,
description:
'우리 모두를 위한 교실, 엘리스와 함께 더 나은 기회를 만들어보세요.',
};
export default function RootLayout({ children }) {
return (
<html>
<head>
<Script
id="educational-org-schema"
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify(jsonLd),
}}
/>
</head>
<body>{children}</body>
</html>
);
}
여기서 주의할 점이 몇 가지 있어요:
- Script 컴포넌트 위치: Next.js의
Script컴포넌트는head안에 넣어야 합니다. 그래야 검색 엔진 크롤러가 페이지를 처음 읽을 때 바로 스키마 정보를 파악할 수 있어요. - id 속성 필수:
id="educational-org-schema"처럼 고유한 id를 꼭 지정해주세요. 같은 페이지에 여러 스키마를 추가할 때 충돌을 방지할 수 있습니다. - type 명시:
type="application/ld+json"을 명확히 써줘야 브라우저와 검색 엔진이 이게 JSON-LD 포맷임을 인식합니다.
4단계: 검증하기
코드를 작성했다고 끝이 아니에요. 제대로 작동하는지 반드시 확인해야 합니다. 저는 두 가지 도구를 사용했어요:
-
Schema Markup Validator: Schema.org 공식 검증 도구입니다. URL을 입력하거나 코드를 직접 붙여넣어서 문법 오류를 체크할 수 있어요.
-
Google의 Rich Results Test: 실제로 구글 검색에서 어떻게 보일지 미리 확인할 수 있습니다. 특히 경고나 에러가 있으면 바로 알려줘서 디버깅할 때 정말 유용해요.
처음에 제가 실수했던 부분이, address 필드에 문자열만 넣었다가 경고가 뜬 거예요. PostalAddress 타입으로 제대로 구조화해야 한다는 걸 그때 알았습니다:
address: {
'@type': 'PostalAddress',
streetAddress: '테헤란로 427, 4층',
addressLocality: '강남구',
addressRegion: '서울특별시',
addressCountry: 'KR'
}
이렇게 바꿨더니 검증 도구에서 모든 체크가 통과되더라고요.
결과
Links
- 관련 문서
- scheme-dts를 이용하여, Layout에 Script 삽입
- schema markup generator
- schema markup
- schema validator
- https://github.com/google/schema-dts: schema.org를 위한 Typescript Types
- Type : EducationalOrganization