I turn coffee into code ☕ → 💻 자세히보기

개발/Next.js

Next.js에서 네이버맵 검색하고 마커 띄우기

xuwon 2025. 9. 7. 21:27

이번에 네이버맵 API를 사용하면서, 위치를 검색해서 등록해야 하는 기능이 있었다.
그래서 직접 프론트에서 지도 검색 API를 사용해보기로 했다!

지도를 보여주는 API는 NCP에서 키를 발급받아 사용했는데, 검색 API는 네이버 개발자 센터에서 키를 발급받아야 한다.

 

NAVER Developers

네이버 오픈 API들을 활용해 개발자들이 다양한 애플리케이션을 개발할 수 있도록 API 가이드와 SDK를 제공합니다. 제공중인 오픈 API에는 네이버 로그인, 검색, 단축URL, 캡차를 비롯 기계번역, 음

developers.naver.com

 

여기서 애플리케이션 등록하면서 사용 API를 '검색'으로 해주면 된다.

클라이언트에서 직접 요청하려고 하면 에러가 발생하기도 하고, API 키(X-Naver-Client-Id, X-Naver-Client-Secret)를 클라이언트에 넣으면
그대로 노출이 되어 보안에 문제가 생기기 때문에 서버에서 호출을 하는 방식으로 진행했다.

 

API Route 사용하기

Next.js(App Router 기준)에서는 app/api/.../route.ts 파일을 만들면 자동으로 API 엔드포인트가 생성된다.
이 엔드포인트에서 네이버 API를 호출하고, 클라이언트는 그 결과만 받아볼 수 있도록 하면 보안 문제가 해결된다!

나는 src/app/api/search-place 이 안에 route.ts를 생성했다.
그러면 사용할 때 /api/search-place 엔드포인트로 접근이 가능하다.

// app/api/search/route.ts
import { NextRequest, NextResponse } from "next/server";

export async function GET(req: NextRequest) {
  // 1. 쿼리 파라미터(keyword) 추출
  const { searchParams } = new URL(req.url);
  const keyword = searchParams.get("keyword");

  if (!keyword) {
    return NextResponse.json({ error: "keyword required" }, { status: 400 });
  }

  // 2. 네이버 API URL 생성
  const url = `https://openapi.naver.com/v1/search/local.json?query=${encodeURIComponent(
    keyword
  )}&display=10`;

  // 3. API 요청 (환경 변수에서 키 가져오기)
  const res = await fetch(url, {
    headers: {
      "X-Naver-Client-Id": process.env.NAVER_CLIENT_ID!,
      "X-Naver-Client-Secret": process.env.NAVER_CLIENT_SECRET!,
    },
  });

  // 4. 요청 실패 처리
  if (!res.ok) {
    return NextResponse.json(
      { error: "네이버맵 API 에러" },
      { status: res.status }
    );
  }

  // 5. 결과 반환
  const data = await res.json();
  return NextResponse.json(data.items);
}

API 키는 .env.local 파일에 저장해놓으면 된다.
클라이언트에서 사용하는 키들은 앞에 NEXT_PUBLIC_을 붙여야 했는데, 이 키들은 서버에서 사용하는 키이기에 안 붙여야 한다!

 

const handleSearch = async () => {
  if (!searchTerm) return;
  setLoading(true);
  try {
    const res = await fetch(
      `/api/search-place?keyword=${encodeURIComponent(searchTerm)}`
    );
    const data: NaverPlace[] = await res.json();
    setResults(data);
    setIsResultOpen(true);
  } catch (err) {
    console.error(err);
  } finally {
    setLoading(false);
  }
};

사용하려는 클라이언트 컴포넌트에서 검색어를 받아서 쿼리스트링으로 보내주면 끝!

이제 이 위치를 마커로 표시해야 한다.
그러면 주소를 좌표로 변환하는 과정이 한 번 더 필요하다.

 

Geocode 함수로 주소를 좌표로 변환하기

이 Geocode 함수는 주소를 위도/경도로 변환해준다.
네이버 지도 SDK에서 제공하고 있어서, NCP에 애플리케이션 등록해서 사용할 수 있다!

 

NAVER CLOUD PLATFORM

cloud computing services for corporations, IaaS, PaaS, SaaS, with Global region and Security Technology Certification

www.ncloud.com

이렇게 등록하면 된다.

const handleSelectPlace = (place: NaverPlace) => {
  if (!window.naver) return;

  const cleanTitle = place.title
    .replace(/<[^>]+>/g, " ")
    .replace(/\s+/g, " ")
    .trim();
  setPlaceName(cleanTitle);
  setSearchTerm(cleanTitle);

  window.naver.maps.Service.geocode(
    { query: place.roadAddress || place.address },
    (status, response) => {
      if (status !== window.naver.maps.Service.Status.OK) return;

      const lat = parseFloat(response.v2.addresses[0].y);
      const lng = parseFloat(response.v2.addresses[0].x);

      setZoom(18);
      setCenter({ lat, lng });
      setMarkers([{ lat, lng, emotion: "기본" as TagVariant }]);
      setIsResultOpen(false);
    }
  );
};

검색된 결과에서 하나를 선택했을 때 실행할 함수!

네이버 검색 API 결과에는 HTML 태그가 포함될 수 있어서, 정규식을 사용해서 태그랑 공백 등을 제거하는 과정을 거쳤다.

window.naver.maps.Service.geocode(
  { query: place.roadAddress || place.address },
  (status, response) => {
    if (status !== window.naver.maps.Service.Status.OK) return;

    const lat = parseFloat(response.v2.addresses[0].y);
    const lng = parseFloat(response.v2.addresses[0].x);

    setZoom(18);
    setCenter({ lat, lng });
    setMarkers([{ lat, lng, emotion: "기본" }]);
    setIsResultOpen(false);
  }
);

주소 문자열을 전달해주면 response.v2.address에 좌표 정보 배열이 들어온다!
y는 위도, x는 경도.

확대 수준, 지도 중심 좌표 등을 설정해주고 좌표 정보까지 전달해주면 마커가 생성된다~

이렇게 사용했다 ㅎㅅㅎ
↓ ↓ ↓ ↓ ↓

다음은 지도 띄우는 걸 한 번 써보려고 한다!

 

 

 

'개발 > Next.js' 카테고리의 다른 글

Next.js에서 네이버맵 API 연동하기  (0) 2025.09.17
Next.js에서 GA 연동하기  (3) 2025.09.17
Next.js + Storybook 연동 기록  (10) 2025.08.15
Next.js의 렌더링 방식 (CSR/SSR/SSG/ISR)  (4) 2025.08.07
[Next.js] 미들웨어  (1) 2025.08.07