목록으로 돌아가기

지역+진료과목 페이지, 프로그래매틱 생성과 지역 검색 신호 설계

지역+진료과목 페이지를 데이터 1개와 공통 템플릿으로 자동 생성하면서 얇은 중복 페이지를 피하는 고유화 기준, MedicalClinic·PostalAddress 스키마 설계, 구글과 네이버의 지역 노출 신호 차이, 의료법 제56조를 지키는 템플릿 안전장치를 정리합니다.

핵심 요약

지역+진료과목 페이지는 데이터 객체 1개와 공통 템플릿으로 자동 생성하되, 페이지마다 고유 canonical·고유 JSON-LD @id·고유 FAQ·고유 오시는길 데이터를 갖게 해야 얇은 중복 페이지 판정을 피할 수 있습니다. 구조화 데이터는 MedicalClinic에 PostalAddress·GeoCoordinates·OpeningHoursSpecification을 붙이고, 환자 후기 성격의 review와 aggregateRating은 의료법 제56조 때문에 넣지 않습니다. 진료과목은 법정 표시과목 명칭 그대로 쓰고, 최상급·치료효과 단정·할인 문구는 데이터 타입 설계와 빌드 단계 검사로 애초에 들어갈 자리를 없앱니다.

핵심 판단
  • 지역 페이지 생성 여부는 검색량이 아니라 그 지역 전용 사실을 3개 이상 쓸 수 있는지로 판단한다.
  • 템플릿은 공유하되 canonical, JSON-LD @id, FAQ, 오시는길 데이터는 페이지마다 반드시 달라야 doorway 판정을 피한다.
  • MedicalClinic 스키마에 review와 aggregateRating을 넣지 않는 것이 일반 업종 로컬 SEO와의 결정적 차이다.
  • 진료과목은 검색어가 아니라 법정 표시과목 명칭으로 표기하고, 근거가 없으면 '전문' 대신 '중점진료'로 쓴다.
  • 구글에서 지역 페이지는 순위 자산 자체지만, 네이버에서는 스마트플레이스 정보 정합성이 먼저이고 홈페이지는 대조군에 가깝다.
  • 금지 표현은 개별 검수가 아니라 데이터 타입 설계와 빌드 단계 어휘 검사로 차단해야 N개 페이지 복제를 막는다.

"강남 정형외과", "부천 소아과" 같은 검색어는 이미 답이 정해진 질문입니다. 검색자는 질환을 공부하려는 게 아니라 지금 갈 수 있는 병원을 고르려는 상태이고, 그래서 이 검색어군은 홈페이지로 들어오는 유입 중 문의·예약까지 경로가 가장 짧습니다. 문제는 이 검색어가 하나가 아니라 대략 (노려볼 만한 지역 수 × 표시과목 수)만큼 존재한다는 점입니다.

여기서 원장님들이 보통 두 갈래로 갑니다. 하나는 홈페이지 메인 한 장으로 모든 지역 검색어를 받으려는 방식이고, 다른 하나는 지역 이름만 치환한 페이지를 수십 장 찍어내는 방식입니다. 앞의 것은 어느 검색어에도 명확히 대응하지 못해 검색엔진이 페이지 주제를 좁히지 못하고, 뒤의 것은 구글이 doorway page(관문 페이지)로 판단해 색인에서 빼거나 평가를 낮출 위험을 만듭니다. 의료는 검색엔진이 특히 보수적으로 다루는 주제군이라, 얇은 페이지를 대량 생산했을 때의 손해가 다른 업종보다 큽니다.

세 번째 길이 프로그래매틱 지역 페이지입니다. 템플릿은 공유하되 데이터는 공유하지 않는 구조로, 페이지 수를 늘리면서도 각 페이지가 고유한 사실을 갖게 만드는 방식입니다. 아래는 웨비스튜디오가 자사 사이트에서 실제로 쓰는 "검색의도 랜딩 팩토리" 구조를 병원·의원 지역 페이지에 옮길 때의 설계 기준과, 의료법 제56·57조 때문에 일반 업종과 달라져야 하는 지점을 정리한 것입니다.

지역 페이지를 만들지 말지부터 정한다

페이지를 늘리는 결정은 검색량이 아니라 "그 지역 전용으로 쓸 수 있는 사실이 있는가"로 판단하는 편이 안전합니다. 검색량은 있는데 쓸 사실이 없으면 그 페이지는 필연적으로 얇아집니다.

판단 질문예 → 별도 페이지아니오 → 만들지 않음
그 지역에 지점·분원이 실제로 있는가지점 전용 페이지(주소·좌표·진료시간 고유)상위 지역 페이지에 통합
지점은 없지만 실제 내원 반경 안인가접근 경로 중심 페이지(노선·소요시간)만들지 않음
그 지역 고유 사실을 3개 이상 쓸 수 있는가생성생성 보류
화면 문구가 옆 지역 페이지와 문장 단위로 다른가생성데이터부터 다시

여기서 "고유 사실 3개"는 실무 임계값으로 쓸 만합니다. 지하철 출구와 도보 시간, 버스 정류장명, 주차 조건, 해당 지점의 요일별 진료시간, 인근 랜드마크, 그 지역에서 자주 들어오는 문의 유형 중 최소 3개를 못 채우면 그 페이지는 만들지 않는 쪽이 총점에 유리합니다.

데이터 1개 + 템플릿 1개로 N개를 만들되, 고유하게

웨비스튜디오 자사 사이트의 검색의도 랜딩은 데이터 객체 하나(searchIntentPages)와 공통 React 템플릿 하나로 구성됩니다. 라우트마다 데이터 키를 넘기면 페이지가 생성되지만, 생성된 페이지는 서로 다음을 공유하지 않습니다.

  • 고유 canonical — createCanonicalAlternates('/' + data.slug)로 페이지마다 자기 slug 기준 대표 URL을 갖습니다.
  • 고유 JSON-LD — @graph 안의 모든 노드가 자기 URL을 @id 접두로 씁니다({url}#faq, {url}#clinic 형태). 두 페이지의 스키마가 같은 @id를 갖는 순간 검색엔진에게는 같은 개체가 됩니다.
  • 고유 FAQ 배열 — 페이지마다 FAQ 질문·답변이 다릅니다.
  • 고유 검색어 목록(focusTerms) — ItemList로 노출되며, 그 페이지가 어떤 질문에 답하는 페이지인지 기계가 읽을 수 있게 합니다.

병원 지역 페이지로 옮기면 공유해도 되는 것과 반드시 달라야 하는 것이 이렇게 갈립니다.

구성 요소공유 가능페이지마다 달라야 함
레이아웃·컴포넌트·CSSO-
진료 절차 설명, 준비물 안내O(사실 기반이면)-
title / description / H1X지역명 + 법정 표시과목 조합
canonicalX자기 URL
JSON-LD @id·주소·좌표·진료시간X지점 실제 값
FAQ 4~6개X최소 절반은 그 지역 전용 질문
오시는길 본문X노선·출구·주차 실제 값
대표 이미지 altX지점명·지역명 반영

배포 전 검수 기준은 단순합니다. 두 지역 페이지를 나란히 놓고 지역명만 가렸을 때 사람이 구분하지 못하면, 검색엔진도 구분하지 않습니다. 그런 페이지는 sitemap에 넣기 전에 되돌립니다.

MedicalClinic 스키마: 무엇을 넣고 무엇을 일부러 빼는가

지역 페이지의 구조화 데이터는 MedicalClinic(상위가 필요하면 MedicalOrganization)을 중심으로, 주소는 PostalAddress, 좌표는 GeoCoordinates, 진료시간은 OpeningHoursSpecification으로 씁니다.

{
  "@context": "https://schema.org",
  "@type": "MedicalClinic",
  "@id": "https://example-clinic.co.kr/bucheon/pediatrics#clinic",
  "name": "○○의원",
  "url": "https://example-clinic.co.kr/bucheon/pediatrics",
  "telephone": "+82-32-000-0000",
  "medicalSpecialty": "Pediatric",
  "address": {
    "@type": "PostalAddress",
    "streetAddress": "○○로 00, 3층",
    "addressLocality": "부천시",
    "addressRegion": "경기도",
    "postalCode": "14000",
    "addressCountry": "KR"
  },
  "geo": { "@type": "GeoCoordinates", "latitude": 37.5035, "longitude": 126.7660 },
  "openingHoursSpecification": [
    { "@type": "OpeningHoursSpecification",
      "dayOfWeek": ["Monday","Tuesday","Wednesday","Thursday","Friday"],
      "opens": "09:00", "closes": "18:30" },
    { "@type": "OpeningHoursSpecification",
      "dayOfWeek": "Saturday", "opens": "09:00", "closes": "13:00" }
  ],
  "areaServed": [{ "@type": "City", "name": "부천시" }],
  "hasMap": "https://map.naver.com/...",
  "sameAs": ["https://map.naver.com/...", "https://www.google.com/maps/..."]
}

필드별 판단 기준은 이렇습니다.

필드넣는 기준흔한 실수
@id페이지 URL 기준 고유 앵커전 지점이 같은 @id
medicalSpecialtyschema.org의 열거값 사용한글 과목명을 그대로 넣어 무시됨
geo지점 실좌표 소수점 4자리 이상지역 중심 좌표를 돌려씀
openingHoursSpecification요일별 분리, 점심·휴진 반영전 지점 동일 시간 하드코딩
areaServed실제 진료권 도시·구전국 나열
sameAs스마트플레이스·구글 지도 등 검증 가능한 프로필SNS만 나열
review / aggregateRating넣지 않음별점 리치 결과 욕심에 삽입

마지막 줄이 의료 분야의 결정적 차이입니다. 일반 업종에서는 aggregateRating이 클릭률 자산이지만, 의료기관 홈페이지에서 환자 후기·평점을 싣는 것은 의료법 제56조 제2항이 금지하는 치료경험담 광고에 해당할 소지가 큽니다. 구조화 데이터는 화면에 있는 내용을 기계용으로 요약한 것이므로, 화면에 실을 수 없는 것은 스키마에도 실을 수 없습니다.

출력 방식도 정해 둡니다. 모든 JSON-LD는 serializeJsonLd로 직렬화해 < 를 \u003c 로 이스케이프한 뒤 <script type="application/ld+json">에 넣습니다. 병원 페이지는 지점명·주소·의료진 표기처럼 운영자가 입력한 값이 그대로 스키마에 들어가기 때문에, 이 한 줄이 스크립트 조기 종료와 주입을 막는 방어선 역할을 합니다.

진료과목은 검색어가 아니라 법정 명칭으로 쓴다

사람들이 검색하는 말과 의료기관이 표시할 수 있는 진료과목 명칭은 다릅니다. 표기는 법정 표시과목을 따르고, 검색어 대응은 본문 문장과 FAQ의 자연어에서 처리하는 것이 안전한 분리입니다.

검색어에서 흔한 표현표기·간판·스키마의 표시과목
소아과소아청소년과
비뇨기과비뇨의학과
정신과정신건강의학과
통증의학과마취통증의학과
성형·피부 통칭성형외과 / 피부과(개설 과목대로)

즉 URL과 H1에는 "부천 소아청소년과"를 쓰고, 본문에는 "부천에서 소아과를 찾으시는 분들이 자주 묻는 내용" 같은 문장으로 검색어를 자연스럽게 포함시킵니다. 표시과목을 검색어에 맞춰 바꾸는 순간 표기 위반이 N개 페이지로 복제됩니다.

'전문'과 '특화'도 같은 원리입니다. 보건복지부 지정 전문병원이거나 법정 전문과목 전문의 자격이라는 근거가 있을 때만 쓰고, 없으면 '중점진료'로 표기합니다. 근거 없이 "○○ 전문 클리닉"이라고 쓰는 대신 "정형외과 전문의 진료", "척추·관절 중점진료"처럼 검증 가능한 사실로 바꿉니다.

오시는길·진료시간·주차: 로컬 신호는 HTML에도 있어야 한다

구조화 데이터만 채우고 화면에는 지도 이미지 한 장만 있는 페이지가 의외로 많습니다. 사용자에게 보이지 않는 내용을 마크업하는 것은 구조화 데이터 정책 위반이고, 실무적으로도 사람이 못 읽는 정보는 전환에 기여하지 않습니다.

  • 주소 전체(도로명 + 건물명 + 층/호)를 선택 가능한 텍스트로 노출. 이미지 안에만 넣지 않기
  • 전화번호는 tel: 링크로. 모바일 검색 유입의 상당수가 통화 의도입니다
  • 요일별 진료시간 표에 점심시간, 야간진료 요일, 휴진일, 공휴일 정책을 분리 표기
  • 주차 조건(건물 주차 가능 여부, 대수, 무료/유료, 제휴 주차장)을 사실대로. 무료 주차는 편의시설 사실이므로 표기 가능하지만, "이달 주차비 지원" 같은 형태로 쓰면 경제적 이익 제공 광고로 읽힐 수 있어 피합니다
  • 대중교통은 호선·출구 번호·도보 분, 버스 정류장 명칭까지
  • 지도는 네이버 지도·카카오맵 링크와 함께, 정적 이미지에는 지점명이 들어간 alt
  • NAP(상호·주소·전화)를 홈페이지, 네이버 스마트플레이스, 구글 비즈니스 프로필에서 문자 단위로 통일. 층 표기 하나가 달라도 동일 개체 판정이 흔들립니다

판단 기준 하나만 기억하면 됩니다. 지점마다 진료시간이 다르면 지점 페이지마다 openingHoursSpecification을 따로 둡니다. 하나를 돌려쓰면 화면과 스키마가 어긋나고, 그 불일치는 검색엔진과 방문자 양쪽에서 동시에 손해입니다.

구글과 네이버는 같은 페이지를 다르게 본다

항목구글네이버
지역 결과의 1차 자산구글 비즈니스 프로필네이버 스마트플레이스
홈페이지 JSON-LD개체 이해·리치 결과에 직접 활용수집은 되나 플레이스 DB가 우선, 보조 신호 성격
등록·점검 도구Search Console네이버 서치어드바이저
sitemap자동 발견 비중 큼서치어드바이저에 직접 제출하는 편이 확실
업종 분류프로필 카테고리플레이스 업종 분류
결과 표면웹 결과 + 지도 팩플레이스·블로그·카페·웹사이트 탭이 분리
홈페이지의 역할순위 자산 그 자체플레이스 정보의 사실 대조군

정리하면, 지역 페이지는 구글에서 직접 순위를 겨루는 자산이고 네이버에서는 플레이스 정보가 실재하고 일관됨을 뒷받침하는 근거 자료에 가깝습니다. 그래서 네이버 중심이라도 지역 페이지를 만들 이유는 충분하지만, 네이버 쪽 개선의 첫 수는 홈페이지가 아니라 스마트플레이스의 업종·주소·진료시간·대표 이미지 정합성입니다. 순서를 뒤집으면 노력 대비 반응이 잘 안 옵니다.

리뷰 지표를 KPI로 잡는 설계는 권하지 않습니다. 환자가 자발적으로 남긴 플랫폼 리뷰 자체와 별개로, 의료기관이 대가나 유인을 제공해 후기를 작성하게 하면 치료경험담 광고 문제로 이어질 수 있고, 그 후기를 홈페이지로 옮겨 싣는 순간에는 명백히 의료기관의 광고물이 됩니다.

의료법이 템플릿 구조 자체를 바꾼다

자체 홈페이지는 의료광고 사전심의 대상 매체가 아니라는 전제로 설계하되, 제56조의 금지 유형은 매체와 무관하게 그대로 적용되고 자율심의기구의 사후 모니터링 대상이 된다는 점을 함께 전제합니다. 프로그래매틱에서 특히 중요한 이유는 산술적입니다. 수동 페이지에서 문구 하나를 잘못 쓰면 위반은 1건이지만, 템플릿에서 잘못 쓰면 지역 수만큼 복제됩니다.

금지 유형템플릿에 스며들기 쉬운 형태대체
치료효과 단정·보장"확실한 개선", "재발 없는", "완치"검사·시술의 절차, 대상, 소요 시간, 준비사항
최상급·비교우위"강남 최고", "1위", "최다", "유일한"개원 연도, 보유 장비 명칭, 진료 요일
치료경험담·후기환자 후기 슬라이더, 실명·이니셜 사례삭제(대체 요소를 두지 않음)
시술 전후 비교before/after 갤러리시설·장비 사진
비급여 할인·이벤트·경품"이달의 프로모션", "지역 주민 혜택"비급여 진료비용 고지만 사실대로

그래서 템플릿 레벨의 안전장치를 코드로 겁니다.

  1. 데이터 타입에 자유 서술 필드를 만들지 않는다. 지역 페이지 데이터 타입을 district, subwayExit, walkMinutes, parking, hours, specialty 같은 사실 필드로만 구성하면, catchphrase 같은 칸이 없으니 최상급 문구가 들어갈 자리도 없습니다. 스키마 설계가 곧 규제 준수 장치가 됩니다.
  2. 표시과목을 유니온 타입으로 고정한다. 법정 표시과목만 값으로 허용해 '소아과'는 타입 에러가 나게 합니다. 사람이 검수하지 않아도 잘못된 표기가 빌드를 통과하지 못합니다.
  3. 금지 어휘 검사를 빌드에 붙인다. 최상급·보장·할인·후기 계열 어휘 사전으로 데이터 파일과 렌더 결과 문자열을 검사하고, 걸리면 빌드를 실패시킵니다. Next.js 15 App Router의 standalone 빌드 파이프라인에 넣으면 배포 이전 단계에서 멈춥니다.
  4. FAQ 답변도 같은 검사를 통과시킨다. FAQPage 구조화 데이터는 생성형 AI 답변에 그대로 인용될 가능성이 있어, 여기에 들어간 한 문장은 검색 결과 밖에서도 재유통됩니다.
  5. 변경 이력을 남긴다. 사후 모니터링이나 민원 대응에서 "언제 무엇을 어떻게 고쳤는지"를 설명할 수 있어야 합니다.

검색·AI 노출은 클릭이나 계약을 보장하지 않습니다. 이 글의 설계는 검색엔진과 생성형 AI가 병원 정보를 정확히 읽고 설명할 가능성을 높이기 위한 것이며, 순위·문의 수·매출을 약속하지 않습니다. 개별 표현의 의료법 위반 여부는 최종적으로 관할 보건소와 자율심의기구의 판단을 따릅니다.

만든 페이지를 기계가 실제로 읽게 만드는 경로

페이지를 잘 만들어도 수집 경로가 없으면 존재하지 않는 것과 같습니다. 웨비스튜디오가 자사 사이트에서 운영하는 방식은 네 갈래입니다.

  • 런타임 /sitemap.xml — 지역 페이지가 데이터에 추가되면 자동 반영됩니다. 정적 파일로 관리하면 페이지를 늘릴 때마다 갱신 누락이 생깁니다.
  • /rss.xml — 콘텐츠 갱신 신호를 별도 채널로 노출합니다.
  • /llms.txt — 생성형 AI와 수집기를 위한 기계 판독용 카탈로그입니다. 지역·진료과목 페이지 목록과 한 줄 설명을 텍스트로 제공하되, 이 문구도 앞서 만든 금지 어휘 검사를 똑같이 통과시킵니다.
  • 내부 링크 구조 — 지역 허브에서 각 지역 상세로, 진료과목 허브에서 지역별 페이지로 양방향 연결해 고아 페이지를 없앱니다. 프로그래매틱 페이지가 색인되지 않는 원인 1순위는 링크가 아예 없다는 것입니다.

실행 순서 체크리스트

  • 지점·진료권을 기준으로 만들 지역 목록을 확정하고, 고유 사실 3개를 못 채우는 지역은 목록에서 제외
  • 표시과목을 법정 명칭 유니온 타입으로 정의
  • 지역 데이터 객체를 사실 필드만으로 설계(자유 서술 칸 없음)
  • 공통 템플릿 1개 작성, 페이지별 canonical·@id·FAQ·오시는길을 데이터에서 주입
  • MedicalClinic + PostalAddress + GeoCoordinates + OpeningHoursSpecification 구성, review/aggregateRating 제외
  • 모든 JSON-LD를 serializeJsonLd로 이스케이프해 출력
  • 금지 어휘 검사를 빌드 단계에 연결하고 실패 시 배포 중단
  • NAP를 홈페이지·스마트플레이스·구글 비즈니스 프로필에서 문자 단위로 일치
  • 런타임 sitemap, rss, llms.txt에 신규 페이지 반영 확인
  • 서치어드바이저·Search Console에서 수집·색인 상태를 페이지 단위로 확인

지역 페이지의 성패는 페이지 수가 아니라 페이지당 사실의 밀도에서 갈립니다. 만들 수 있는 페이지를 다 만드는 대신 근거를 채울 수 있는 페이지만 만들고, 그 근거를 화면과 구조화 데이터에 동일하게 싣고, 의료법 금지 표현이 들어갈 자리를 데이터 구조에서 미리 없애는 것. 이 세 가지가 자동 생성 방식을 안전하게 만드는 조건입니다.

자주 묻는 질문

지역명만 치환하고 나머지 문장이 동일하면 구글이 doorway page로 판단해 색인에서 제외하거나 평가를 낮출 수 있습니다. 기준은 페이지 수가 아니라 고유성입니다. 지점 주소와 좌표, 요일별 진료시간, 지하철 출구와 도보 시간, 주차 조건, 그 지역 전용 FAQ처럼 페이지마다 다른 사실이 실려 있고 canonical과 JSON-LD의 @id가 각각 고유하면 자동 생성 자체는 문제가 되지 않습니다.

권하지 않습니다. review와 aggregateRating은 일반 업종에서는 리치 결과에 유리한 필드지만, 의료기관 홈페이지에서 환자 후기와 평점을 싣는 것은 의료법 제56조 제2항이 금지하는 치료경험담 광고에 해당할 소지가 있습니다. 구조화 데이터는 화면 내용을 기계용으로 요약한 것이므로, 화면에 실을 수 없는 내용은 스키마에도 넣지 않는 원칙으로 설계합니다.

표기는 법정 표시과목 명칭을 따릅니다. URL, H1, 스키마의 진료과목 표기는 소아청소년과로 쓰고, 검색어 대응은 본문 문장이나 FAQ에서 '소아과를 찾으시는 분들이 자주 묻는 내용'처럼 자연어로 처리합니다. 비뇨기과는 비뇨의학과, 정신과는 정신건강의학과처럼 구어와 법정 명칭이 다른 과목은 동일한 방식으로 분리합니다.

네이버 지역 노출이 목표라면 홈페이지보다 네이버 스마트플레이스의 업종 분류, 주소, 진료시간, 대표 이미지 정합성을 먼저 정리하는 편이 반응이 빠릅니다. 구글은 홈페이지 지역 페이지 자체가 순위 자산이므로 구조화 데이터와 페이지 고유화의 효과가 더 직접적입니다. 두 채널 모두 상호명·주소·전화번호 표기가 문자 단위로 일치해야 같은 기관으로 인식됩니다.

아닙니다. 사전심의 대상 매체가 아니라는 것과 의료법 제56조의 금지 유형이 적용되지 않는다는 것은 다른 이야기입니다. 치료효과 단정, 최상급 표현, 환자 치료경험담, 시술 전후 비교, 비급여 할인·이벤트·경품은 자체 홈페이지에서도 금지되며 자율심의기구의 사후 모니터링 대상이 됩니다. 특히 템플릿 기반 페이지는 문구 하나의 오류가 생성된 페이지 수만큼 복제되므로 더 보수적으로 설계합니다.

페이지가 수십 개로 늘어나면 검수 누락이 구조적으로 발생합니다. 데이터 타입에 자유 서술 필드를 만들지 않아 최상급 문구가 들어갈 칸 자체를 없애고, 표시과목을 유니온 타입으로 고정해 잘못된 명칭이 타입 에러가 나게 하며, 최상급·보장·할인·후기 계열 어휘 사전으로 데이터와 렌더 결과를 검사해 걸리면 빌드를 실패시키는 방식이 더 안정적입니다. FAQ 답변도 동일한 검사를 통과시켜야 합니다.

병원·의원 홈페이지 제작이 필요하신가요?
상담 문의를 남겨주시면 제작 방향을 함께 정리해 드립니다.