Next.js(React)에서 네이버 지도 API 깔끔하게 연동하기

안녕하세요! 이번 포스트에서는 Next.js (React) 프로젝트에서 네이버 지도 API를 연동하는 방법을 알아보겠습니다. 국내 사용자를 대상으로 하는 서비스를 개발한다면 네이버 지도 연동은 필수적인 기능 중 하나인데요. Next.js의 렌더링 방식과 React의 Hook을 활용하여 깔끔하고 효율적으로 구현하는 과정을 단계별로 소개해 드리겠습니다.

시작하기 전에: 네이버 클라우드 플랫폼 설정

가장 먼저 네이버 클라우드 플랫폼에서 애플리케이션을 등록하고 Client ID를 발급받아야 합니다. 이 ID는 API 인증에 사용되므로, 없다면 아래 공식 가이드를 참고하여 준비해 주세요.

타입스크립트를 사용하는 분은 타입 정의 파일을 설치하고 코드를 작성해야 합니다.

Step 1: 네이버 지도 API 스크립트 로드하기

Next.js에서 외부 스크립트를 로드할 때는 next/script 컴포넌트를 사용하는 것이 가장 좋습니다. 페이지 로딩을 최적화하고 스크립트 로딩 시점을 제어할 수 있기 때문입니다.

app/layout.tsx에 아래와 같이 <Script> 태그를 추가합니다.

// app/contact/page.tsx 또는 지도가 필요한 다른 페이지

import Script from "next/script";

export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
  return (
    <html lang="ko">
      <body>
        <Script strategy="beforeInteractive" src={`https://oapi.map.naver.com/openapi/v3/maps.js?ncpKeyId=${process.env.NEXT_PUBLIC_NAVER_MAP_CLIENT_ID}`} />
        {children}
      </body>
    </html>
  );
}

주요 포인트:

  • strategy="beforeInteractive": 페이지가 상호작용 가능해지기 전에 스크립트를 실행하여, 지도 API(window.naver)가 컴포넌트 렌더링 시점에 존재하도록 보장합니다.
  • Client ID 관리: 실제 ID를 코드에 하드코딩하는 대신, .env.local 파일에 환경변수로 저장하고 process.env를 통해 불러오는 방식을 권장합니다. (NEXT_PUBLIC_ 접두사가 있어야 클라이언트에서 접근 가능합니다.)

Step 2: 지도 표시를 위한 React 컴포넌트 생성하기

이제 지도를 실제로 렌더링할 컴포넌트를 만듭니다. useRef로 지도를 담을 DOM 요소를 참조하고, useEffect를 사용해 컴포넌트가 마운트된 후에 지도 생성 로직을 실행합니다.

// components/ContactUsMap.tsx

"use client";

import { useRef, useEffect } from "react";

export default function ContactUsMap() {
  const naver = typeof window !== "undefined" && window.naver;

  // 지도를 담을 DOM 요소에 대한 ref 생성
  const mapElement = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    // window.naver 객체가 로드되었는지, ref가 유효한지 확인
    if (!naver || !mapRef.current) return;

    // 위도
    const latitude = 37.5716229;
    // 경도
    const longitude = 126.9767879;

    // 지도의 중심 좌표 설정
    const location = new naver.maps.LatLng(latitude, longitude);

    // 지도 옵션 설정
    const mapOptions: naver.maps.MapOptions = {
      center: location,
      zoom: 17,
      zoomControl: true, // 줌 컨트롤 표시
      scaleControl: false, // 스케일 컨트롤 비표시
    };

    // 지도 인스턴스 생성
    const map = new naver.maps.Map(mapElement.current, mapOptions);

    // 지도 위에 마커 생성
    new naver.maps.Marker({
      position: location,
      map: map,
    });
  }, []); // 컴포넌트가 처음 마운트될 때 한 번만 실행

  return (
    // 지도가 렌더링될 div 요소
    <div ref={mapElement} style={{ minHeight: "400px" }} />
  );
}

Step 3: 코드 핵심 분석

  • "use client": useRef, useEffect와 같은 React Hook과 window 객체에 접근하려면 클라이언트 컴포넌트로 선언해야 합니다.
  • useRef<HTMLDivElement>: mapElement라는 ref를 생성하여 JSX의 <div> 요소와 연결합니다. 네이버 지도 API는 이 DOM 요소를 컨테이너로 사용해 지도를 렌더링합니다.
  • useEffect(() => { ... }, []): 이 Hook은 컴포넌트가 클라이언트에서 렌더링되고 DOM에 마운트된 직후에 실행됩니다. window.naver API와 mapElement.current(실제 <div> 요소)에 안전하게 접근할 수 있는 최적의 시점입니다. 의존성 배열을 []로 비워두어 최초 렌더링 시 한 번만 실행되도록 합니다.
  • new naver.maps.Map(...): naver.maps 라이브러리를 사용하여 지도 인스턴스를 생성합니다. 첫 번째 인자로는 지도를 담을 DOM 요소(mapElement.current)를, 두 번째 인자로는 지도 옵션(중심 좌표, 줌 레벨 등)을 전달합니다.
  • new naver.maps.Marker(...): 지도 위에 표시할 마커를 생성하고, map 속성에 지도 인스턴스를 지정하여 마커를 지도에 추가합니다.

마치며

지금까지 Next.js 환경에서 next/script와 React Hook을 활용해 네이버 지도 API를 연동하는 방법을 알아보았습니다. 이 패턴을 활용하면 서버사이드 렌더링(SSR)과 클라이언트 렌더링이 혼합된 Next.js 환경에서도 외부 스크립트 기반 라이브러리를 안정적으로 통합할 수 있습니다.

여기서 더 나아가 커스텀 컨트롤 추가, 정보 창(InfoWindow) 표시 등 다양한 기능은 네이버 지도 API 공식 문서를 참고하여 구현해 보시길 바랍니다.

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다