728x90
- 무엇: 웹페이지에 지도를 넣고(표시/이동/확대), 마커·오버레이, 장소 검색, 주소↔좌표 변환, 마커 클러스터링, 도형 그리기 등을 제공하는 JS API.
- 어떻게: Kakao 개발자 콘솔에서 앱 생성→Web 플랫폼 도메인 등록→JavaScript 키 발급 후, SDK 스크립트를 로드하여 사용.
- 추가 도구: 지도 URL(링크)로 지도/길찾기/로드뷰/검색결과를 직접 여는 패턴 제공.
키 발급 & 도메인 등록 (필수)
- 카카오 개발자 사이트 접속 → 로그인.
- 내 애플리케이션에서 앱 생성.
- 앱 설정 → 플랫폼 → Web 플랫폼 등록에서 사이트 도메인 등록
- 앱 키 → JavaScript 키를 복사하여 SDK
appkey
로 사용.
주의: 등록된 도메인에서만 JS 키가 동작합니다. 운영/개발(로컬) 도메인을 각각 등록하세요.
로컬 테스트(정적 서버)
- Python 3:
cd /path/to/your/folder python3 -m http.server 8080
- Node(http-server):
npx http-server -p 8080
브라우저에서 http://localhost:8080 접속. (로컬 도메인을 Web 플랫폼에 등록해야 동작)
최소 예제로 지도 띄우기
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Kakao 지도 시작하기</title>
<style>
/* 지도가 보이려면 width/height가 필수 */
#map { width: 500px; height: 400px; }
</style>
</head>
<body>
<div id="map"></div>
<!-- 필수: 발급받은 JavaScript 키 사용 -->
<script src="//dapi.kakao.com/v2/maps/sdk.js?appkey=YOUR_JS_KEY"></script>
<script>
// 1) 컨테이너와 옵션
const container = document.getElementById('map');
const options = {
center: new kakao.maps.LatLng(33.450701, 126.570667), // 위도,경도
level: 3
};
// 2) 지도 생성
const map = new kakao.maps.Map(container, options);
</script>
</body>
</html>
center는 반드시 설정해야 합니다(위도→경도 순).
확장 라이브러리 로드(services/clusterer/drawing)
- 한 번에 필요한 라이브러리만 선택해서 로드합니다.
<script src="//dapi.kakao.com/v2/maps/sdk.js?appkey=YOUR_JS_KEY&libraries=services,clusterer,drawing"></script>
services
: 장소 검색, 주소↔좌표 변환clusterer
: 마커 클러스터링drawing
: 마커/도형 그리기 UI
지도 URL로 “지도/길찾기/로드뷰/검색결과” 바로 열기
- 지도 보기
/link/map/위도,경도
/link/map/이름,위도,경도
/link/map/장소ID
- 길찾기(이동수단: car/traffic/walk/bicycle)
/link/to/이름,위도,경도
/link/from/…/to/…
/link/by/{car|traffic|walk|bicycle}/…
- 로드뷰:
/link/roadview/위도,경도
또는 장소ID - 검색결과:
/link/search/검색어
→ 사용 환경에 따라 PC/모바일웹 카카오맵으로 자동 연결.
<!-- 예: 목적지로 길찾기 -->
<a target="_blank"
href="https://map.kakao.com/link/to/카카오판교아지트,37.3952969470752,127.110449292622">
카카오맵 길찾기 열기
</a>
비동기 로딩(autoload=false) & Lazy Load 패턴
autoload=false
로 SDK를 “불러만 두고”, 필요 시kakao.maps.load(() => {...})
에서 초기화 코드를 실행할 수 있습니다.- 단, SDK 스크립트 요청 시점에 이미 쿼터가 소모됩니다(로드 후 콜백과 무관). 정말 필요할 때 스크립트를 동적으로 주입하는 방식으로 최적화하세요.
<script>
function injectKakaoSdk(cb) {
if (window.kakao && window.kakao.maps) return cb();
const s = document.createElement('script');
s.src = "//dapi.kakao.com/v2/maps/sdk.js?appkey=YOUR_JS_KEY&autoload=false&libraries=services,clusterer,drawing";
s.onload = () => kakao.maps.load(cb);
document.head.appendChild(s);
}
// 필요 시점에 호출
injectKakaoSdk(() => {
const map = new kakao.maps.Map(document.getElementById('map'), {
center: new kakao.maps.LatLng(37.5665, 126.9780), level: 5
});
// … 추가 초기화
});
</script>
300x250
자주 쓰는 실전 코드 스니펫
1) 마커 + 인포윈도우
const pos = new kakao.maps.LatLng(37.5665, 126.9780);
const marker = new kakao.maps.Marker({ position: pos, map });
const iw = new kakao.maps.InfoWindow({ content: '<div style="padding:8px">서울시청</div>' });
kakao.maps.event.addListener(marker, 'click', () => iw.open(map, marker));
2) 지도 이벤트(클릭 시 좌표 표시)
kakao.maps.event.addListener(map, 'click', (mouseEvent) => {
const latlng = mouseEvent.latLng;
console.log('위도:', latlng.getLat(), '경도:', latlng.getLng());
});
3) 주소 → 좌표(Geocoder) + 마커
// libraries=services 필요
const geocoder = new kakao.maps.services.Geocoder();
geocoder.addressSearch('서울특별시 중구 세종대로 110', (result, status) => {
if (status === kakao.maps.services.Status.OK) {
const coords = new kakao.maps.LatLng(result[0].y, result[0].x);
new kakao.maps.Marker({ map, position: coords });
map.setCenter(coords);
}
});
services 라이브러리의 Geocoder 사용.
4) 키워드(장소) 검색 + 리스트/마커
// libraries=services 필요
const ps = new kakao.maps.services.Places();
ps.keywordSearch('카페', (data, status) => {
if (status !== kakao.maps.services.Status.OK) return;
data.forEach(place => {
const coords = new kakao.maps.LatLng(place.y, place.x);
new kakao.maps.Marker({ map, position: coords });
});
});
5) 마커 클러스터링
// libraries=clusterer 필요
const clusterer = new kakao.maps.MarkerClusterer({
map, averageCenter: true, minLevel: 7
});
const markers = coordsArray.map(c => new kakao.maps.Marker({ position: new kakao.maps.LatLng(c.lat, c.lng) }));
clusterer.addMarkers(markers);
6) 그리기 모드(도형/거리 측정 UI)
// libraries=drawing 필요
const options = {
map, drawingMode: [kakao.maps.drawing.OverlayType.POLYLINE, kakao.maps.drawing.OverlayType.POLYGON],
guideTooltip: ['draw', 'drag', 'edit']
};
const manager = new kakao.maps.drawing.DrawingManager(options);
// 예: 그리기 시작/종료는 manager API로 제어
7) 길찾기/로드뷰/검색 URL 열기
// 목적지로 길찾기(자동차)
window.open('https://map.kakao.com/link/by/car/출발지명,37.5665,126.9780/도착지명,37.3952969470752,127.110449292622', '_blank');
// 로드뷰
window.open('https://map.kakao.com/link/roadview/37.5665,126.9780', '_blank');
URL 패턴은 공식 가이드를 참고하세요.
React/SPA에서의 로딩 팁
- 초기 1회만 SDK 주입: 상단의
injectKakaoSdk()
유틸로 중복 로딩 방지. - 컴포넌트 마운트 시점에 지도 생성:
useEffect
에서kakao.maps.load
콜백 안에서 생성. - 라우팅 전환 시 메모리 관리: 지도/오버레이/리스너 참조를 모아 언마운트 때 해제.
window.kakao 존재 확인 후 초기화하는 패턴을 권장(전역 SDK).
보안 점검 체크리스트
A. 키 & 도메인 통제
- 환경 분리: 운영/개발/테스트 각각 별도 앱/키 권장.
- 도메인 화이트리스트 정확성:
https
포함, 서브도메인 범위, 로컬(http://localhost:8080
) 등록 확인. - 키 노출 방지: 공개 저장소/정적 HTML에 직접 하드코딩 금지. 배포 파이프라인에서 템플릿 치환(예:
.env
→CI/CD 주입).
B. 스크립트/콘텐츠 보안
- HTTPS 강제 + CSP(script-src, connect-src 최소화).
- 라이브러리 최소 로드:
services,clusterer,drawing
중 필요한 것만. - Lazy Load: 정말 필요할 때만 SDK를 동적 주입(쿼터/로드 최적화).
C. 입력값 검증 & 개인정보
- URL/좌표 파라미터 검증: 사용자 입력으로 지도 URL을 조립할 때 인젝션/오픈 리다이렉트 점검.
- 위치정보 최소화/동의 절차: 정밀 좌표 공개 전 사전 고지, 마스킹/일반화 고려.
D. 사용량/장애 대비
- 호출·오류·지연 모니터링: 클러스터링/검색 결과 캐싱, 초기 지도 생성 최소화(탭 전환 시 로드).
- 쿼터 초과 대응: 에러 핸들링·폴백 화면·재시도 정책.
E. 내부 점검 체크리스트
- 키 보관(비밀관리), 노출 스캔, 권한 최소화
- Web 플랫폼 도메인 정확성(프로토콜/서브도메인/로컬 포함)
- HTTPS, CSP, 중복 스크립트 로딩 방지
- 라이브러리 최소·지연 로딩 설계
- 지도 URL/입력값 검증, 위치정보 보호
- 모니터링/알림, 장애 대응·요금 관리
트러블슈팅(실무에서 자주 겪는 문제)
- ❗ kakao가 undefined: SDK가 아직 로드 전입니다. →
autoload=false
+kakao.maps.load()
콜백에서 초기화하거나,onload
이후 실행. - ❗ 지도가 안 보임: 컨테이너에 width/height 누락.
- ❗ 도메인 오류: Web 플랫폼에 등록되지 않은 도메인에서 호출.
- ❗ 과도한 네트워크 로드: 페이지 전환마다 SDK 재로딩 → 중복 로딩 방지 유틸 사용.
확장 예시 모음(복붙용)
1) 반경 N m 내 카페 검색 + 마커
// services 필요
const ps = new kakao.maps.services.Places();
const center = new kakao.maps.LatLng(37.5665, 126.9780);
ps.keywordSearch('카페', (data, status) => {
if (status !== kakao.maps.services.Status.OK) return;
data.filter(p => kakao.maps.geometry ? true : true) // (geometry 제공 X, 반경 필터는 앱 로직으로)
.forEach(p => new kakao.maps.Marker({ map, position: new kakao.maps.LatLng(p.y, p.x) }));
}, { location: center, radius: 1000 }); // m 단위
2) 대량 마커 클러스터링
// clusterer 필요
const clusterer = new kakao.maps.MarkerClusterer({ map, averageCenter:true, minLevel:6 });
const markers = bigList.map(p => new kakao.maps.Marker({ position:new kakao.maps.LatLng(p.lat, p.lng) }));
clusterer.addMarkers(markers);
3) 다각형(폴리곤)으로 서비스 구역 표시
const path = [
new kakao.maps.LatLng(37.57, 126.98),
new kakao.maps.LatLng(37.58, 126.99),
new kakao.maps.LatLng(37.56, 127.01)
];
const polygon = new kakao.maps.Polygon({
map, path, strokeWeight:2, strokeColor:'#333', fillColor:'#00AEEF', fillOpacity:0.3
});
4) 지하철 노선도 길찾기(서울)
<a target="_blank" href="https://map.kakao.com/link/by/subway/seoul/판교역/강남역">
카카오맵 지하철 길찾기
</a>
활용 시나리오(아이디어)
- 매장/지점 찾기(Store Locator): 주소→좌표 변환 + 마커 + 클러스터링
- 배달 가능 구역: 폴리곤으로 범위 시각화, 범위 밖 주문 안내
- 부동산/숙박 지도: 수천 개 매물 클러스터링 + 상세 오버레이
- 내부 운영 지도: 설비/사고 위치 실시간 마킹, URL로 길찾기 안내
성능·운영 팁(대량 데이터 기준)
- 마커/오버레이 재사용(show/hide)로 GC/재생성 비용 감소
- 지연 로딩 & 가시 범위만 그리기(bounds 내 데이터만)
- 결과 캐싱(장소/지오코딩)과 요청 합치기로 API 호출 절감
- 쿼터 초과 대비: 사용자 메시지/폴백 제공, 서버 캐시로 완화
보안 점검표(배포 직전 10분 체크)
- JavaScript 키 노출 스캔(Git/정적 파일) & 비밀관리 반영
- Web 플랫폼 도메인 정확성(https/서브도메인/localhost)
- SDK 중복 로딩 금지,
autoload=false
+ 동적 주입 설계 - CSP 적용(script-src/connect-src 최소)
- 입력값 검증(지도 URL, 위/경 범위) & 위치정보 최소화
- 모니터링: 오류율/지연/호출량 알림
공식 문서(필독)
- Kakao 지도 Web API 가이드(라이브러리·지도 URL 패턴·예시)
- Kakao Developers — JavaScript SDK 시작하기(앱/플랫폼 등록 흐름)
- DevTalk —
autoload=false
와 로딩/쿼터 이슈 설명
728x90
그리드형(광고전용)
댓글