fix: 500 error caused by leaflet being imported server side

This commit is contained in:
2026-06-13 11:42:47 +00:00 Unverified
parent 4ed54ad315
commit d6f12377b8
3 changed files with 37 additions and 25 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ const { isAuthenticated, user, logout } = useAuth()
<button class="btn btn-primary btn-icon btn-full border-0" @click="logout" <button class="btn btn-primary btn-icon btn-full border-0" @click="logout"
data-element="personal-area-logout" data-focus-mouse="false"> data-element="personal-area-logout" data-focus-mouse="false">
<span class="rounded-icon" aria-hidden="true"> <span class="rounded-icon" aria-hidden="true">
<BIIcon name="it-logout" color="white" /> <BIIcon name="it-logout" color="black" />
</span> </span>
<span class="d-none d-lg-block">Esci</span> <span class="d-none d-lg-block">Esci</span>
</button> </button>
+35 -24
View File
@@ -1,20 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import type { Category, CreateReportRequest } from '~/types/api' import type { Category, CreateReportRequest } from '~/types/api'
import type { LeafletMouseEvent, Map as LeafletMap, Marker as LeafletMarker } from 'leaflet'
import { onMounted, onUnmounted, ref, watch } from 'vue' import { onMounted, onUnmounted, ref, watch } from 'vue'
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'
// Fix per le icone di Leaflet in Nuxt/Vite
const DefaultIcon = L.icon({
iconUrl: 'https://unpkg.com/[email protected]/dist/images/marker-icon.png',
iconRetinaUrl: 'https://unpkg.com/[email protected]/dist/images/marker-icon-2x.png',
shadowUrl: 'https://unpkg.com/[email protected]/dist/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
});
L.Marker.prototype.options.icon = DefaultIcon;
interface Props { interface Props {
isLoading?: boolean isLoading?: boolean
@@ -47,10 +34,35 @@ const isGettingLocation = ref(false)
// Map variables // Map variables
const mapContainer = ref<HTMLElement | null>(null) const mapContainer = ref<HTMLElement | null>(null)
let map: L.Map | null = null let leaflet: typeof import('leaflet') | null = null
let marker: L.Marker | null = null let map: LeafletMap | null = null
let marker: LeafletMarker | null = null
const initMap = () => { const loadLeaflet = async () => {
if (leaflet) return leaflet
const leafletModule = await import('leaflet')
// Fix per le icone di Leaflet in Nuxt/Vite
const defaultIcon = leafletModule.icon({
iconUrl: 'https://unpkg.com/[email protected]/dist/images/marker-icon.png',
iconRetinaUrl: 'https://unpkg.com/[email protected]/dist/images/marker-icon-2x.png',
shadowUrl: 'https://unpkg.com/[email protected]/dist/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowSize: [41, 41]
})
leafletModule.Marker.prototype.options.icon = defaultIcon
leaflet = leafletModule
return leaflet
}
const initMap = async () => {
if (!import.meta.client || !mapContainer.value || map) return
const L = await loadLeaflet()
if (!mapContainer.value || map) return if (!mapContainer.value || map) return
// Centro Italia default // Centro Italia default
@@ -64,7 +76,7 @@ const initMap = () => {
attribution: '&copy; OpenStreetMap contributors' attribution: '&copy; OpenStreetMap contributors'
}).addTo(map) }).addTo(map)
map.on('click', (e: L.LeafletMouseEvent) => { map.on('click', (e: LeafletMouseEvent) => {
updateLocation(e.latlng.lat, e.latlng.lng) updateLocation(e.latlng.lat, e.latlng.lng)
}) })
@@ -78,9 +90,9 @@ const updateLocation = (lat: number, lng: number, zoomTo = false) => {
form.value.latitude = Number(lat.toFixed(6)) form.value.latitude = Number(lat.toFixed(6))
form.value.longitude = Number(lng.toFixed(6)) form.value.longitude = Number(lng.toFixed(6))
if (map) { if (map && leaflet) {
if (!marker) { if (!marker) {
marker = L.marker([lat, lng]).addTo(map) marker = leaflet.marker([lat, lng]).addTo(map)
} else { } else {
marker.setLatLng([lat, lng]) marker.setLatLng([lat, lng])
} }
@@ -95,7 +107,7 @@ const updateLocation = (lat: number, lng: number, zoomTo = false) => {
} }
onMounted(() => { onMounted(() => {
// Map logic is handled by ClientOnly placeholder if needed, but we initialize here void initMap()
}) })
onUnmounted(() => { onUnmounted(() => {
@@ -186,10 +198,10 @@ watch(() => form.value.category_id, () => {
// Sincronizza input manuali con la mappa // Sincronizza input manuali con la mappa
watch([() => form.value.latitude, () => form.value.longitude], ([newLat, newLng]) => { watch([() => form.value.latitude, () => form.value.longitude], ([newLat, newLng]) => {
if (newLat && newLng && map) { if (newLat && newLng && map && leaflet) {
if (!marker || marker.getLatLng().lat !== newLat || marker.getLatLng().lng !== newLng) { if (!marker || marker.getLatLng().lat !== newLat || marker.getLatLng().lng !== newLng) {
if (!marker) { if (!marker) {
marker = L.marker([newLat, newLng]).addTo(map) marker = leaflet.marker([newLat, newLng]).addTo(map)
} else { } else {
marker.setLatLng([newLat, newLng]) marker.setLatLng([newLat, newLng])
} }
@@ -382,4 +394,3 @@ textarea {
+1
View File
@@ -45,6 +45,7 @@ export default defineNuxtConfig({
}, },
css: [ css: [
'leaflet/dist/leaflet.css',
'bootstrap-italia/dist/css/bootstrap-italia.min.css', 'bootstrap-italia/dist/css/bootstrap-italia.min.css',
'@/assets/css/style.css' '@/assets/css/style.css'
], ],