vue.jsvuejs2leafletnuxt.jsnuxtjs2

The geography display on the leaflet map does not appear in nuxtjs version 2


Package installed: leaflet: ^1.9.4 nuxt: ^2.0.0 node: 14.21.3` npm: 6.14.18
The problem: The geography display on the leaflet map does not appear, I used GeoJSON.

enter image description here

I have written the initials of the leaflet correctly along with the CSS style link in the head nuxt. the map should run correctly, but it doesn't.

This is my code:

<template>
  <div class="relative w-100">
    <div id="map"></div>
  </div>
</template>

<script>
export default {
  name: 'CTFMapV2',
  head() {
    return {
      link: [
        {
          rel: 'stylesheet',
          href: 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css',
        },
      ],
    }
  },
  data() {
    return {
      L: null,
      map: null,
      zoom: 5,
      center: [-3, 117],
      geoJsonData: null,
      geoOptions: {
        interactive: false,
        style: {
          weight: 2,
          opacity: 1,
          color: '#27354a',
          dashArray: '3',
          fillOpacity: 0.7
        }
      },
      LMapOptions: {
        dragging: false,
        boxZoom: false,
        zoomControl: false,
        scrollWheelZoom: false,
        doubleClickZoom: false
      },
      popupOptions: {
        closeButton: false,
        className: 'map-popup',
        interactive: true,
        maxWidth: 330,
        autoPan: false,
        keepInView: true,
        offset: [0, 0],
        autoPanPaddingTopLeft: [0, 0],
        autoPanPaddingBottomRight: [0, 0]
      },
      iconSize: 22
    }
  },
  computed: {
    dynamicSize() {
      return [this.iconSize, this.iconSize]
    },
    dynamicAnchor() {
      return [this.iconSize / 2, this.iconSize / 1.5]
    }
  },
  mounted() {
    this.initialMap()
  },
  methods: {
    async initialMap() {
      this.L = require('leaflet')
      this.map = this.L.map('map', {
        center: this.center,
        ...this.LMapOptions
      })
      this.L.geoJSON(await this.loadGeoJsonData(), this.geoOptions).addTo(
        this.map
      )
    },
    badgeVariant(level) {
      const lv = level.toLowerCase()
      if (lv === 'easy') return 'success'
      else if (lv === 'medium') return 'warning'
      else if (lv === 'hard') return 'danger'
      return 'secondary'
    },
    async loadGeoJsonData() {
      try {
        const response = await fetch(
          'https://raw.githubusercontent.com/eppofahmi/geojson-indonesia/master/provinsi/all_maps_state_indo.geojson'
        )
        const idn = await response.json()
        return idn
      } catch (error) {
        console.error('Error loading GeoJSON:', error)
      }
    },
    createIcon({ img }) {
      return this.L.icon({
        iconUrl: img,
        iconSize: this.dynamicSize,
        iconAnchor: this.dynamicAnchor,
        popupAnchor: [0, 0]
      })
    },
    createMarker({ icon, coordinate, map, content }) {
      const marker = this.L.marker(coordinate, { icon }).addTo(map)

      const popup = this.L.popup().setContent(content)

      marker.on('mouseover', function() {
        marker.openPopup()
      })
      popup.on('mouseout', function() {
        popup.closePopup()
      })

      marker.bindPopup(popup)
      return marker
    }
  }
}
</script>

<style scope>
#map {
  background-color: #161d2a;
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}
</style>

Here I did an initial leaflet map on the mounted nuxt, then I set it to retrieve GeoJSON data (I have made sure the GeoJSON data exists and is valid).


Solution

  • I think you need to add the following code in public/index.html

    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
    

    and Include Leaflet JavaScript file after Leaflet’s CSS

     <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha25620nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="crossorigin=""></script>