교육 사이트 전 페이지에 SEO 메타·구조화 데이터 적용
목차
사이트 전반의 SEO 메타태그와 JSON-LD 구조화 데이터를 한꺼번에 보강했다. 단순히 <title> 몇 개 고치는 수준이 아니라, 교육 도메인에 맞는 스키마 타입까지 새로 끌어들인 작업이었음.
왜 지금 이 작업이었나
사실 기능 개발 백로그 한켠에 항상 있던 일이다. "나중에 하자"는 말 뒤에 계속 밀려 있다가, 검색 유입 분석을 다시 들여다봤을 때 명확하게 보였다. 메타가 제대로 안 붙어 있으면 SNS 공유 시 미리보기가 깨지고, 구글 크롤러 입장에서도 페이지가 무슨 콘텐츠인지 파악하기 어려워진다. 특히 교육 관련 서비스는 EducationalOrganization과 Course 스키마를 정확하게 붙여두면 구글 리치 결과(Rich Results)에 노출될 수 있는 여지가 생긴다. 이걸 놓치고 있던 게 아까웠음.
팀 입장에서도 "마케팅·콘텐츠 팀이 SNS에 링크 뿌릴 때 카드가 왜 안 나오냐"는 피드백이 계속 들어오고 있었고, 그 원인의 상당 부분이 OG 태그 미비였다. 기능 개발보다 우선순위를 올릴 이유가 충분했다.
실제로 건드린 것들
변경된 파일은 6개로 크지 않지만, 영향 범위는 사이트 전체다.
| 파일 | 주요 변경 |
|---|---|
index.html |
홈 OG/Twitter Card 메타, EducationalOrganization JSON-LD 추가 |
courses.html |
강좌 목록 페이지 메타 정비, 스키마 보강 |
course-detail.html |
Course JSON-LD 스키마 추가, 개별 강좌 OG 메타 |
about.html |
기관 소개 페이지 OG + 구조화 데이터 연결 |
contact.html |
기본 메타 정비 |
og.png |
SNS 공유 시 사용될 대표 이미지 추가 |
og.png를 static/ 에 박아두고 모든 템플릿에서 절대경로로 참조하는 방식을 택했다. 페이지마다 다른 썸네일을 쓰는 구조는 나중 과제로 남기고, 일단 기본 대표 이미지 하나라도 제대로 붙이는 게 급선무였음.
<!-- Twitter Card 기본 패턴 -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="...">
<meta name="twitter:description" content="...">
<meta name="twitter:image" content="/og.png">
<!-- Course JSON-LD 기본 구조 -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Course",
"name": "...",
"description": "...",
"provider": {
"@type": "EducationalOrganization",
"name": "..."
}
}
</script>
JSON-LD는 인라인 <script> 블록으로 <head> 안에 배치했다. 마이크로데이터 방식도 있지만, 템플릿 구조를 크게 건드리지 않아도 되고 유지보수도 훨씬 편하다. 특히 Thymeleaf 템플릿에서 동적 값을 주입해야 하는 course-detail.html은 타입이 고정된 JSON-LD 블록 안에 서버사이드 표현식을 끼워 넣는 형태라, 따옴표 이스케이프 처리를 주의해야 했음.
회고 — 이 작업에서 배운 것
SEO 작업은 "나중에 해도 되는 일"처럼 보이지만, 실제로는 누적된 손해가 조용히 쌓인다. 크롤러가 이미 잘못된 정보로 페이지를 인덱싱해 놓으면 수정 후에도 반영되기까지 시간이 걸린다. 빠르게 붙여두는 게 맞다.
몇 가지 짚어두고 싶은 포인트:
og:image는 최소 1200×630px 권장. 작은 이미지는 플랫폼마다 다르게 처리되거나 아예 무시된다- Twitter Card와 OG 태그는 겹치는 값이 많지만 별도로 명시하는 게 안전하다. Twitter가 OG를 fallback으로 읽긴 하지만
twitter:card타입은 명시 없이 작동하지 않음 - JSON-LD의
EducationalOrganization과Course는 구글 Search Console의 리치 결과 테스트에서 바로 검증 가능하다. 작업 직후 돌려보면 오류 잡기 편함 - 템플릿이 서버사이드 렌더링 기반이면, 페이지별 메타를 레이아웃 프래그먼트로 분리해두는 구조가 장기적으로 훨씬 관리하기 낫다. 이번엔 각 템플릿에 직접 작성했는데, 다음 리팩터링 때는
<th:block>추출로 중복을 줄일 여지가 있음
코드리뷰 때도 "이 값이 동적으로 바뀌어야 하지 않냐"는 질문이 나왔다. 맞는 지적이다. 강좌 상세 페이지는 동적 주입이 들어갔지만, 나머지 정적 페이지들은 현재 하드코딩 상태다. 콘텐츠 변경 주기가 얼마나 되는지 봐서 CMS 연동 여부를 판단하기로 팀과 합의했음.
작은 커밋처럼 보여도, 검색과 공유 채널을 통해 들어오는 첫인상에 직접 영향을 준다. 이런 류의 작업일수록 "지금 당장 눈에 안 보이니까 나중에"가 아니라, 사이트 론칭 초기에 같이 챙겨두는 게 팀 전체의 시간을 아끼는 일이다.
끝.
🛒 이 글과 어울리는 추천 상품
*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.
댓글 0
첫 댓글 달아줘.