구글의 구조화된 데이터로 검색순위 높이기

오준상·2024년 9월 5일
11
post-thumbnail

구조화된 데이터는 뭐신지요?

구조화된 데이터는 구글에서 제공하는 페이지의 의미에 관한 단서를 제공하여 내용을 파악하는데 도움을 주는 데이터 입니다.

라고 말씀드리면 이해가 잘 안가실 것 같아서 예시 자료를 들고 와 보겠습니다.
아래 사진을 봐주세요.

구글 검색 결과에 위 사진과 같은 포맷으로 노출되는 경우를 본 적 있으신가요?
위와 같은 검색 결과를 얻기 위해서는 구글에서 제공하는 포맷의 구조화된 데이터를 추가해야합니다.

그럼 이런 생각을 할 수 있을 것 같은데요.

???: 이거 또 저런 동영상이나 제품만 되는거 아니야?

라고 생각하실 수 있는데, 구조화된 데이터에는 꽤나 다양한 종류가 있습니다.

도서, 캐러셀, 과정 정보, 교육 Q&A, 채용, 동영상, 장소, 교육 등등

구글에서 설명하기를 Rotten Tomatoes, Food Network, Nesle 같은 글로벌 사이트에서 많은 유입 효과를 얻었다고 설명하고 있습니다.

그렇게 좋다고 하니, 제가 저희 회사 로드맵 페이지에 도입해서 어느정도의 유입 결과가 있었는지 확인해보겠습니다.

구조화된 데이터 어떻게 생겼지?

일단 구조화된 데이터 자체는 json-ld format으로 제공해야 합니다.
다른 방법도 있는데, json+ld format을 구글에서 권장하고 있고 이용하기에도 가장 편합니다.

적용 방법은, 제가 추후 기술할 format에 맞게 html에 포함시켜주시면 됩니다. html에 값을 넣을 수 있는 SSR이나 SSG에서 유용합니다.

기본적인 구조는 아래와 같습니다.

<html>
  <head>
    <title>뭔가 타이틀</title>
    <script type="application/ld+json">
    { 
      <-- 여기가 실질적인 json+ld입니다. ->
      "@context": "https://schema.org/",
      "@type": "Recipe",
      "name": "Party Coffee Cake",
      "author": {
        "@type": "Person",
        "name": "Mary Stone"
      },
      "datePublished": "2018-03-10",
      "description": "This coffee cake is awesome and perfect for parties.",
      "prepTime": "PT20M"
    }
    </script>
  </head>
  <body>
    뭔가 콘텐츠겠죠?
  </body>
</html>

되게 복잡해 보이지만, 구글에서 이용하고 싶은 케이스별로 예시를 제공하고 있습니다.

그래서 어떻게 썼는데?

일단 제가 구조화된 데이터를 도입하려는 페이지는 로드맵 상세 이라는 페이지입니다. (깨알 로드맵 홍보)
기본적으로 여러 강의와 책, 영상을 묶어놓는 기능이라고 생각하시면 편합니다.

기가막히게 구글에서 적합한 구조화된 데이터 포맷을 제공해 주더라고요.
바로 과정 정보 라는 포맷입니다.

구조화된 데이터 필수값 파악

우선 해당 페이지 하단의 구조화된 데이터 유형 정의 를 확인합니다.

여기에서 포맷에 반드시 필요한 데이터와 옵셔널한 값을 확인할 수 있습니다. 더 자세한 값은 여기서 확인 가능합니다
적혀있는것에 따르면, Course가 필수라고 적혀있네요.

필수값과 옵셔널을 적절히 조합하여 저희가 고른 구조화된 데이터 포맷은 아래와 같습니다

type Course = {
	name: string;
  	description: string;
	provider: {
      "@type": "Organization", // 이 객체가 어떤 타입인지. 구글에 타입에 대한 설명 있음
      "name": "Jurkey" // 과정 진행 업체 이름,
      "url"?: 'https://exampleOrganization.org' // 과정 진행 업체 관련 주소, 옵셔널
    };
	offers: {
      "@types": "Offer",
      "categoryt": "Paid", // 유무료 여부,
      "priceCurrency": "EUR", // 통화
      "price": 10 // "가격"
    };
    hasCourseInstance: [{
     "@type": "CourseInstance",
     "courseMode": "Onsite", // 강의 타입
     "courseSchedule": { // 강의 스케쥴
        "@type": "Schedule",
        "repeatCount": 4, // 걸리는 시간
        "repeatFrequency": "Weekly", // 걸리는 시간의 단위
     },
     "instructor"?: [{ // 필수는 아님
        "@type": "Person",
        "name": "Kai S.", // 해당 과정 진행자 명
        "description": "Professor at X-University", // 과정 설명
        "image": "http://examplePerson.jpg" // 과정 이미지
     }]
  }]
}

구조화된 데이터를 채우고 html에 넣기

저희는 Next.js를 사용하고 있어서 간단하게pages/index.tsx 에 데이터 매칭 후 값을 넣어주는 작업을 하였습니다.
코드는 아래와 같습니다.

export const GoogleRichResult = ({ response }: Props) => {
  const applicationLdJson = {
    '@context': 'https://schema.org',
    '@type': 'Course',
    name: response.roadmap.title,
    description: `${response.roadmap.skills
      .slice(0, 2)
      .map((skill) => skill.title)
      .join(', ')} 스킬을 학습할 수 있는 ${
      response.roadmap.category
    } 로드맵을 확인해 보세요.`,
    publisher: {
      '@type': 'Organization',
      name: response.roadmap.authorName,
      url: PAGE_ENDPOINT.profile(response.roadmap.authorId, response.roadmap.authorSlug),
    },
    offers: response.items.courseItems.map((course) => ({
      '@type': 'Offer',
      price: '가격',
      priceCurrency: 'KRW',
      url: '과정 주소',
      category: course.price === 0 ? 'Free' : 'Paid',
    })),
    provider: {
      '@type': 'Organization',
      name: '회사명',
      url: '회사 페이지 주소',
    },
    hasCourseInstance: response.items.courseItems.map((course) => ({
      '@type': 'CourseInstance',
      name: course.title,
      courseMode: 'Online',
      courseWorkload: calculate8601Duration(course.runtime ?? 0),
    })),
  };

  return (
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{
        __html: JSON.stringify(applicationLdJson),
      }}></script>
  );
};
  
const calculate8601Duration = (runtime: number) => { // 구글에서 원하는 날짜 포맷
  const dayForMillisecond = 60 * 60 * 24;
  const hourForMillisecond = 60 * 60;

  const day = Math.floor(runtime / dayForMillisecond);
  const hours = Math.floor((runtime % dayForMillisecond) / hourForMillisecond);
  const minutes = Math.floor((runtime % hourForMillisecond) / 60);

  return `P${day ? `${day}D` : ''}T${hours ? `${hours}H` : ''}${minutes ? `${minutes}M` : ''}`;
};

위에서 정의한 값과 가지고 있는 데이터를 매칭하는 작업을 하여 아래와 같이 사용하기만 하면 됩니다.

const Page = () => {
	// ....
  const response = apicall();
  return (
    <main>
      // .. 
     <GoogleRichResult response={response} />
    </main>
  )
}

구조화된 데이터가 잘 적용되고 있는지 어떻게 테스트하지?

이는 구글에서 제공하는 테스트 도구를 이용하면 됩니다.

개발하고 계실때는 html 코드를 긁어다 붙이시면 되고, 완료된 페이지는 URL로 테스트 하시면 됩니다.

이번에 도입된 로드맵 상세 페이지는 아래와 같은 결과가 나옵니다.

그래서 뭐가 얼마나 좋아졌는데?

사실 이런말 하면 그렇지만 위에서 도입한 과정 정보는 아직 검색 결과에서 특별한 UI를 제공하지 않습니다.

구글 서치 콘솔 기준으로 검색결과 평균 노출 순위가 배포 직전에 12.5등까지 갔었던것에 반해, 배포 후 11.8등까지 올라간 것을 확인했습니다. (그래프는 사내 정보라 공유가 안됩니다 ㅠ)

현재는 특별한 UI가 제공되지 않아서 드라마틱한 효과는 없지만 구글 검색 엔진 순위에 영향을 주는것으로 확인됩니다.

마무리

지금까지 어떻게 구조화된 데이터를 도입했고, 어느정도의 성과가 있었는지 알려드렸습니다.
드라마틱하지 않지만 영향이 있고, 추후 UI가 제공된다면 더 높은 성과를 기대할 수 있을 것 같습니다.

만약 SSR, SSG를 이용해서 서비스를 구축하고 있다면 도입을 고려해보는걸 추천드립니다.

긴 글 읽어주셔서 감사합니다.

profile
만들고싶은걸만듭니다

0개의 댓글