LoginSignup
2
2

Next.jsでGoogle Mapsを表示する方法

Last updated at Posted at 2024-05-21

はじめに

この記事では、Next.jsアプリケーションでGoogle Maps APIを使用して地図を表示する方法について説明します。具体的には、Material-UIを使用したコンポーネント構成と、Google Maps APIの非同期読み込みを実装します。

環境設定

Google Maps APIのキーを取得し、環境変数に設定します。.env.localファイルに以下のように記載します。

.env.local
NEXT_PUBLIC_GOOGLE_MAP_KEY=your_google_maps_api_key

ファイル構成

以下は、この記事で紹介したNext.jsアプリケーションのファイル構成です。

my-next-app/
├── .env.local //環境変数を記入
├── package.json
├── tsconfig.json
├── next.config.js
├── src/
│   ├── pages/
│   │   └── index.tsx
│   └── utils/
│       ├── loadGoogleMapsAPI.ts
│       └── initMap.ts
├── public/
│   └── (静的ファイルがあればここに配置)
└── (その他の設定ファイルやディレクトリ)

コンポーネントの作成

以下のコードは、Next.jsでGoogle Mapsを表示するコンポーネントの実装です。

index.tsx

index.tsxファイルは、地図を表示するメインコンポーネントです。

index.tsx
import { Box, Container } from '@mui/material'
import type { NextPage } from 'next'
import { useEffect, useState } from 'react'
import { loadGoogleMapsAPI } from '@/utils/loadGoogleMapsAPI'

const Index: NextPage = () => {
  const [map, setMap] = useState<google.maps.Map | null>(null)

  useEffect(() => {
    loadGoogleMapsAPI(setMap)
  }, [])

  return (
    <>
      <Container maxWidth="xl">
        <Box id="map" style={{ height: '80vh', width: '100%' }}></Box>
      </Container>
    </>
  )
}

export default Index

loadGoogleMapsAPI.ts

次に、Google Maps APIを非同期に読み込む関数を実装します。この関数は、APIの読み込みが完了した後に地図を初期化します。

loadGoogleMapsAPI.ts
import { initMap } from './initMap'

interface GoogleMapsConfig {
  key?: string // オプショナルに変更
  v: string
  [key: string]: string | undefined // インデックスシグネチャを追加
}

export const loadGoogleMapsAPI = (
  setMap: React.Dispatch<React.SetStateAction<google.maps.Map | null>>,
) => {
  ;((g: GoogleMapsConfig) => {
    let h: Promise<void> | null = null
    const p = 'The Google Maps JavaScript API'
    const c = 'google'
    const l = 'importLibrary'
    const q = '__ib__'
    const m = document

    let b: any = window
    b = b[c] || (b[c] = {})
    const d = b.maps || (b.maps = {})
    const e = new URLSearchParams()

    const u = () => {
      if (!h) {
        //GoogleMapsAPIのスクリプトが読み込まれるのを待つ
        h = new Promise<void>((resolve, reject) => {
          const a = m.createElement('script') as HTMLScriptElement
          //クエリパラメータの設定キー バリュー
          e.set('libraries', '')
          for (const k in g) {
            if (g[k]) {
              e.set(
                k.replace(/[A-Z]/g, (t) => '_' + t[0].toLowerCase()),
                g[k] as string,
              )
            }
          }
          e.set('callback', c + '.maps.' + q)
          //Google Maps APIのURLとクエリパラメータを設定
          a.src = `https://maps.${c}apis.com/maps/api/js?` + e
          //resolve
          d[q] = resolve
          //rejects
          a.onerror = () => reject(new Error(p + ' could not load.'))
          //ドキュメントの属性を検索
          a.nonce =
            (m.querySelector('script[nonce]') as HTMLScriptElement)?.nonce || ''
          //document.head要素に新しいscript要素aを追加
          m.head.append(a)
        })
      }
      //Promiseをリターンする
      return h
    }

    if (!d[l]) {
      d[l] = (f: string, ...n: any[]) => u().then(() => d[l](f, ...n))
      return u().then(() => {
        // マップを表示する
        initMap(setMap)
      })
    }
  })({
    key: process.env.NEXT_PUBLIC_GOOGLE_MAP_KEY,// 環境変数
    v: 'beta',
  })
}

initMap.ts

最後に、地図を初期化する関数を実装します。この関数は、指定されたDOM要素にGoogle Mapを表示します。

initMap.ts
export const initMap = async (
  setMap: React.Dispatch<React.SetStateAction<google.maps.Map | null>>,
) => {
  const mapElement = document.getElementById('map')

  if (mapElement) {
    const map = new google.maps.Map(mapElement, {
      zoom: 16,
      mapId: 'DEMO_MAP_ID',
      maxZoom: 25,
      center: { lat: 35.681236, lng: 139.767125 },//東京駅を中心
    })

    setMap(map)
  } else {
    console.error('Google Maps API is not available')
  }
}

GoogleMapの表示

Image from Gyazo

結論

以上で、Next.jsアプリケーションにGoogle Mapsを統合する方法について説明しました。これにより、Google Mapsを使用した地図表示が簡単に実現できます。ぜひ、ご自身のプロジェクトに取り入れてみてください。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2