검색 결과에서 다른 사이트는 깔끔하게 주소가 표시되는데, 자신의 사이트만 URL이 뜨지 않거나 오류가 표시되는 경험을 해봤을까. 대부분의 개발자들은 이걸 단순히 구글의 알고리즘 문제라고 생각하거나, 무작정 Search Console에서 재크롤링을 요청하곤 한다. 하지만 실제 원인은 검색 결과 페이지에서 사이트를 식별하고 주소를 표시하기 위해 필요한 구조화 데이터가 제대로 구현되지 않았기 때문이다. 이번에는 Schema.org Organization과 LocalBusiness 마크업을 통해 검색 결과에 내 사이트 주소를 올바르게 표시하는 방법을 완벽하게 정리해서 소개하겠다.

 

왜 검색 결과에 내 사이트 주소가 안 뜰까

구글 검색 결과에서 사이트 주소(URL)는 단순히 메타 태그만으로는 표시되지 않는다. 검색 엔진이 사이트의 실체를 파악하기 위해서는 명확한 구조화 데이터가 필요하다. 특히 로컬 비즈니스나 기업 사이트인 경우, Organization이나 LocalBusiness 스키마가 없으면 검색 결과에 주소는커녕 사이트명도 제대로 표시되지 않을 수 있다.

구글 크롤러는 html 페이지의 텍스트로만 주소를 찾으려 하지 않는다. 대신 JSON-LD 형태의 구조화 데이터를 읽어서 Organization이나 LocalBusiness 내에 명시된 주소 정보(streetAddress, addressLocality, addressRegion, postalCode)를 인식한다. 이 정보가 정확하게 마크업되어 있지 않으면, 검색 결과에서 주소 필드 자체가 나타나지 않는다.

 

기초 개념: Schema.org Organization vs LocalBusiness

먼저 두 가지 스키마의 차이를 이해해야 한다. Organization은 온라인 회사나 단체 전반을 나타내고, LocalBusiness는 물리적 위치를 가진 오프라인 사업체를 나타낸다.

구분 Organization LocalBusiness
용도 온라인 기업, 언론사, 블로그 등 물리적 주소를 가진 오프라인 사업체
주소 필수 여부 선택사항 필수(물리적 위치 정보 포함)
전화번호 선택사항 권장(고객 연락 용도)
영업 시간 미지원 지원(openingHoursSpecification)

온라인 쇼핑몰이나 서비스 회사라면 Organization을 사용하면 되지만, 실제 오프라인 매장이나 지점이 있다면 LocalBusiness를 사용해야 검색 결과에서 주소와 전화번호, 영업 시간까지 함께 표시될 수 있다.

 

Organization 스키마로 기업 정보 마크업하기

온라인 기반 회사라면 Organization 스키마를 사이트의 <head> 또는 <body>에 JSON-LD 형태로 추가하면 된다.

✗ 잘못된 코드

<head>
  <script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@type": "Organization",
    "name": "REDINFO",
    "url": "https://redinfo.blog"
  }
  </script>
</head>

이 코드는 기본 정보만 담고 있어서 주소가 전혀 표시되지 않는다. 검색 결과에 주소를 표시하려면 address 속성이 필수다.

✓ 올바른 코드

<head>
  <script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@type": "Organization",
    "name": "REDINFO",
    "url": "https://redinfo.blog",
    "logo": "https://redinfo.blog/logo.png",
    "sameAs": [
      "https://facebook.com/redinfo",
      "https://twitter.com/redinfo"
    ],
    "address": {
      "@type": "PostalAddress",
      "streetAddress": "서울시 강남구 테헤란로 123",
      "addressLocality": "서울",
      "addressRegion": "서울시",
      "postalCode": "06234",
      "addressCountry": "KR"
    },
    "contactPoint": {
      "@type": "ContactPoint",
      "contactType": "Customer Service",
      "telephone": "+82-2-1234-5678",
      "email": "info@redinfo.blog"
    }
  }
  </script>
</head>

이제 streetAddress, addressLocality, postalCode가 명시되어 있으므로 구글 크롤러가 이 정보를 읽고 검색 결과에 주소를 표시할 수 있다. contactPoint를 추가하면 전화번호도 함께 표시된다.

 

LocalBusiness 스키마로 지역 사업체 정보 마크업하기

실제 오프라인 매장이나 지점이 있다면 LocalBusiness를 사용해야 한다. 이 스키마는 구글 지도와도 연동되므로, 올바르게 설정하면 검색 결과에 위치, 전화, 영업 시간이 모두 표시된다.

<head>
  <script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@type": "LocalBusiness",
    "name": "REDINFO 강남점",
    "url": "https://redinfo.blog/gangnam",
    "image": "https://redinfo.blog/gangnam-store.jpg",
    "description": "개발자 커뮤니티 및 교육 센터",
    "address": {
      "@type": "PostalAddress",
      "streetAddress": "서울시 강남구 테헤란로 123",
      "addressLocality": "서울",
      "addressRegion": "서울시",
      "postalCode": "06234",
      "addressCountry": "KR"
    },
    "geo": {
      "@type": "GeoCoordinates",
      "latitude": "37.4979",
      "longitude": "127.0276"
    },
    "telephone": "+82-2-1234-5678",
    "email": "gangnam@redinfo.blog",
    "openingHoursSpecification": {
      "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
      "opens": "10:00",
      "closes": "20:00"
    },
    "priceRange": "$$"
  }
  </script>
</head>

LocalBusiness에는 latitude, longitude 좌표도 포함되므로 구글 지도에서 정확한 위치 표시가 가능하다. openingHoursSpecification을 추가하면 검색 결과에 "영업 중" 또는 "영업 종료" 표시도 나타난다.

 

주의사항: 흔한 마크업 실수

✗ 실수 1: 주소 형식이 잘못된 경우

address를 단순 문자열로 작성하면 안 된다. 반드시 PostalAddress 객체로 세분화해야 한다.

// 잘못된 예
"address": "서울시 강남구 테헤란로 123"

// 올바른 예
"address": {
  "@type": "PostalAddress",
  "streetAddress": "서울시 강남구 테헤란로 123",
  "addressLocality": "서울",
  "postalCode": "06234",
  "addressCountry": "KR"
}

✗ 실수 2: 전화번호 형식 오류

전화번호는 반드시 국제 형식(+82-2-1234-5678) 또는 하이픈 없는 형식(+82212345678)으로 작성해야 한다. 그래야 구글 크롤러가 인식한다.

// 잘못된 예
"telephone": "02-1234-5678"

// 올바른 예
"telephone": "+82-2-1234-5678"

✗ 실수 3: 다중 지점 마크업 누락

여러 지점이 있다면 각 페이지마다 다른 LocalBusiness 마크업을 추가해야 한다. 메인 페이지에 모든 지점을 한 번에 마크업하면 검색 엔진이 혼동한다.

 

PHP로 동적 JSON-LD 생성하기

하드코딩 대신 PHP에서 동적으로 JSON-LD를 생성하면 데이터베이스 변경 시에도 자동 반영된다.

<?php
$org_data = array(
    "@context" => "https://schema.org",
    "@type" => "LocalBusiness",
    "name" => "REDINFO 강남점",
    "url" => "https://redinfo.blog/gangnam",
    "address" => array(
        "@type" => "PostalAddress",
        "streetAddress" => "서울시 강남구 테헤란로 123",
        "addressLocality" => "서울",
        "addressRegion" => "서울시",
        "postalCode" => "06234",
        "addressCountry" => "KR"
    ),
    "telephone" => "+82-2-1234-5678",
    "email" => "gangnam@redinfo.blog",
    "geo" => array(
        "@type" => "GeoCoordinates",
        "latitude" => "37.4979",
        "longitude" => "127.0276"
    )
);
?>
<head>
  <script type="application/ld+json">
    <?php echo json_encode($org_data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); ?>
  </script>
</head>

json_encode()에 JSON_UNESCAPED_UNICODE 옵션을 추가하면 한글이 유니코드로 변환되지 않고 그대로 출력된다. 이렇게 하면 구글 크롤러가 더 쉽게 주소를 인식할 수 있다.

 

Google Search Console에서 검증하기

마크업을 완료한 후 반드시 Google Search Console의 '리치 결과 테스트' 도구로 검증해야 한다. 이 도구는 실제 마크업을 크롤링해서 오류를 찾아낸다.

Search Console 내 리치 결과 테스트(https://search.google.com/test/rich-results)에 자신의 페이지 URL을 입력하면 JSON-LD 마크업이 올바른지 확인할 수 있다. 만약 "주소"나 "연락처" 필드에 오류 표시가 뜨면, 위의 포스트 주소 형식이나 전화번호 형식을 다시 확인해야 한다.

 

마무리: 작은 마크업이 모아지면 큰 검색 노출이 된다

검색 결과에 주소가 표시되는지 여부는 단순해 보이지만, 사실 구조화 데이터의 정확성에 달려 있다. 이 글의 Organization과 LocalBusiness 마크업 예제를 참고해 자신의 사이트에 적용하면, 검색 결과에서 주소, 전화, 영업 시간이 모두 표시될 것이다. Search Console 리치 결과 테스트로 반드시 검증한 후, 오류가 없다면 재크롤링을 요청하자. 일주일 정도면 검색 결과에 반영될 것이다.