kakao api는 키를 발급받아야 사용가능하며, 키를 발급받았다는 전제하에 작성하였습니다. kakao든 google이든 하루에 무료로 제공되는 횟수는 정해져 있으니 확인해 보고 본인에게 맞는 서비스를 선택하면 될 것 같아요.
*kakao api 키 발급하기 가이드 및 map api 전체 가이드
테스트용 도메인: http://localhost:3000
https://apis.map.kakao.com/web/guide/#ready
1. 루트경로에 .env 파일 생성하여 키값 세팅하기
# .env
NEXT_PUBLIC_KAKAO_APP_KEY=de100000010f46c4a290000000
kakao에서 받은 api key는 .env 파일에 넣어 사용합니다.
2. 지도 화면 출력하기
kakao에서 제공하는 map api 가이드는 초보도 따라 하기 쉽게 잘 정리해져 있지만, next.js로 적용하려 하니 역시 호락호락하지는 않았어요. 😖
div로 지도 영역 설정하기
// Map.tsx
export default function Map() {
return <div id="map" className="w-[500px] h-[400px] bg-grey-40"></div>;
}
먼저, 하나의 컴포넌트를 만들어 id값이 map인 div를 보여주고자 하는 크기로 설정합니다.
지도 띄우기
// Map.tsx
import { useEffect } from 'react';
declare global {
interface Window {
kakao: any;
}
}
export default function Map() {
useEffect(() => {
const mapScript = document.createElement('script');
mapScript.async = true; //해당 스크립트는 비동기로 동작함을 선언.
mapScript.src = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${process.env.NEXT_PUBLIC_KAKAO_APP_KEY}&autoload=false`;
document.head.appendChild(mapScript); //head안에 위에서 만든 script를 넣어줌.
const onLoadKakaoMap = () => {
window.kakao.maps.load(() => {
const mapContainer = document.getElementById('map');
const mapOption = {
center: new window.kakao.maps.LatLng(33.450701, 126.570667), // 지도의 중심좌표 (경도,위도)
level: 3, // 지도의 확대 레벨
};
new window.kakao.maps.Map(mapContainer, mapOption);
});
};
// script의 로드가 끝난 이후에, onLoadKakaoMap을 실행함을 의미
mapScript.addEventListener('load', onLoadKakaoMap);
}, []);
return <div id="map" className="w-[500px] h-[400px] bg-grey-40"></div>;
}
next.js에는 index.html 파일이 따로 없기도 하고, 기능구현에 필요한 관련된 값들을 컴포넌트 하나에서 관리하고 싶었기에 useEffect를 사용하여 직접 script 태그를 만들고 kakao map 라이브러리를 불러서 지도를 그렸어요
이때, 지도를 그리는 함수는 꼭 라이브러리가 로드된 후 실행되어야 합니다.
또한 타입스크립트를 사용한다면, kakao는 정의되지 않았다고 에러를 주기 때문에 최상단에서 any로 타입을 선언하여 사용했습니다.
3. 주소 입력하여 지도 화면 출력하기 (+ 마커)
제공하는 기본 예시는 보여주고 싶은 위치의 경도와 위도를 입력해야만 해당 위치로 지도를 띄워주는 예제입니다.
주소가 변경될 때마다 매번 위도, 경도를 검색해서 입력하는 것도 번거롭고 사용자가 직접 설정하는 것도 불친절하기 때문에 주소를 입력하면 해당하는 위치가 보이는 기능이 필요할 것 같았습니다.
import { useEffect } from 'react';
declare global {
interface Window {
kakao: any;
}
}
export default function Map() {
const address = '서울 종로구 세종로 1-68';
useEffect(() => {
const mapScript = document.createElement('script');
mapScript.async = true;
mapScript.src = `//dapi.kakao.com/v2/maps/sdk.js?appkey=${process.env.NEXT_PUBLIC_KAKAO_APP_KEY}&libraries=services&autoload=false`;
document.head.appendChild(mapScript);
const onLoadKakaoMap = () => {
window.kakao.maps.load(() => {
const mapContainer = document.getElementById('map');
const mapOption = {
center: new window.kakao.maps.LatLng(0, 0), // 지도의 중심좌표 (경도 & 위도)
level: 3, // 지도의 확대 레벨
};
const map = new window.kakao.maps.Map(mapContainer, mapOption);
// 주소로 좌표 검색
const geocoder = new window.kakao.maps.services.Geocoder();
geocoder.addressSearch(address, function (result: any, status: any) {
if (status === window.kakao.maps.services.Status.OK) {
const coords = new window.kakao.maps.LatLng(
result[0].y,
result[0].x
);
map.setCenter(coords);
// 마커 표시
const marker = new window.kakao.maps.Marker({
map: map,
position: coords,
});
marker.setMap(map);
}
});
// 추가적인 옵션 기능 (줌 & 지도타입)
});
};
mapScript.addEventListener('load', onLoadKakaoMap);
}, []);
return <div id="map" className="w-[500px] h-[400px] bg-grey-40" />;
}
⭐️ 우선, 해당 기능을 사용하려면 api를 불러오는 주소 뒤 파라미터로 &libraries=services 를 추가해 주어야 합니다
초기 지도 그림 -> 주소로 설정한 위치 그림 -> 주소로 설정한 위치에 마커 표시
초기에 위치, 경도를 설정한 부분이 먼저 그려지고 위에 주소로 설정한 부분이 그려지기 때문에, 경도 & 위도 입력값을 0으로 초기화한 후 services로 제공하는 Geocoder를 사용하여 주소를 입력하고 위치 값을 받아 그려줍니다.
옵션. (줌 / 지도 타입)
// 지도 & 스카이뷰 옵션
const mapTypeControl = new window.kakao.maps.MapTypeControl();
map.addControl(
mapTypeControl,
window.kakao.maps.ControlPosition.TOPRIGHT
);
// 줌 옵션
const zoomControl = new window.kakao.maps.ZoomControl();
map.addControl(zoomControl, window.kakao.maps.ControlPosition.RIGHT);
결과 화면
사용한 기능 이외에 다양한 기능을 제공하고 있으니 원하는 기능을 공식문서를 보면서 추가하면 좋을 것 같습니다
https://marklee1117.tistory.com/82
https://apis.map.kakao.com/web/documentation/
'Web > React & Next.js' 카테고리의 다른 글
React | Next.js 환경에서 나이스(PASS) 신원인증 구현하기 (0) | 2023.11.05 |
---|---|
React | 서버없이 메일 보내기 및 구글스프레드시트에 저장 (2) | 2023.06.07 |
Next.js 에서 Next/Image를 사용하여 이미지 처리하기 (0) | 2023.02.16 |
Next.js | Next.js + Styled-Components 초기 세팅 (next 13) (0) | 2023.02.14 |
Next.js | Next.js + typescript 초기 세팅 (next 13) (0) | 2023.02.14 |