3

I'm trying to migrate my existing SPA Vue app to NuxtJS framework to take benefits of SSR.

In my current app, I'm using the following directives to load my dependencies:

 <script>     
 import L from 'leaflet';
 import '@geoman-io/leaflet-geoman-free';
 import 'leaflet.markercluster';
 import { Tooltip, Carousel } from 'bootstrap'; 
 import 'leaflet-fullscreen';
 import 'leaflet-sidebar';
 import 'leaflet.vectorgrid';
 export default {
  name: 'carte',
  props: ['gps'],
  components: {
    GChart,
  },
  data() {
...
},
...
}
</script>

When loading the component, I get the "window is not defined" error from Nuxt.

Do you know how to get over this error? If possible, I don't want to load plugins globally because I need those modules only for that component.

Please note that I'm not using Nuxt-leaflet or Vue-leaflet as they do not work with Vue 3.

Thanks a lot!

Sam85
  • 149
  • 8

3 Answers3

5

Using the native leaflet library, I managed to get it work with the following code:

plugins/leaflet.client.ts

import L from 'leaflet'
import 'leaflet.markercluster';
import 'leaflet-fullscreen';
import 'leaflet-sidebar';
import 'leaflet.vectorgrid';
export default defineNuxtPlugin(nuxtApp => {
  return {
      provide: {
        L
      }
    }
})

and in my component using leaflet:

mounted () {
  // Patch for Vectorgrid with Leaflet >= 1.8
  L.DomEvent.fakeStop = function () {
    return true;
  }
  this.$nextTick(function () {
    this.initcarte();
  })
},

where initcarte() is:

const map = L.map("map")
map.setView([lat, lng], zoom)

and I had to change my app.vue to include a parameter in NuxtPage to force component reload on route change:

<NuxtPage :key="$route.fullPath" />

Probably not perfect, but it's working.

kissu
  • 40,416
  • 14
  • 65
  • 133
Sam85
  • 149
  • 8
2

In SSR mode, the server doesn't have a window object. You need to wait for the "onMounted" event, which happens on the client side, meaning the window object is available. I looked around and I found this library that is compatible with Vue 3, but if you just want to import the classic javascript library, you still may find the "Working with leaflet" section helpful.

Nicola Spadari
  • 549
  • 3
  • 10
1

if you use nuxtjs ,You can use the <client-only> component to achieve a similar dynamic import effect and dynamically import your map component, I got this to work,it's so simple:

<template>
  <client-only>
    <YourComponent /> 
  </client-only>
</template>
glory
  • 11
  • 1