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"
data-element="personal-area-logout" data-focus-mouse="false">
<span class="rounded-icon" aria-hidden="true">
<BIIcon name="it-logout" color="white" />
<BIIcon name="it-logout" color="black" />
</span>
<span class="d-none d-lg-block">Esci</span>
</button>
+35 -24
View File
@@ -1,20 +1,7 @@
<script setup lang="ts">
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 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 {
isLoading?: boolean
@@ -47,10 +34,35 @@ const isGettingLocation = ref(false)
// Map variables
const mapContainer = ref<HTMLElement | null>(null)
let map: L.Map | null = null
let marker: L.Marker | null = null
let leaflet: typeof import('leaflet') | 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
// Centro Italia default
@@ -64,7 +76,7 @@ const initMap = () => {
attribution: '&copy; OpenStreetMap contributors'
}).addTo(map)
map.on('click', (e: L.LeafletMouseEvent) => {
map.on('click', (e: LeafletMouseEvent) => {
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.longitude = Number(lng.toFixed(6))
if (map) {
if (map && leaflet) {
if (!marker) {
marker = L.marker([lat, lng]).addTo(map)
marker = leaflet.marker([lat, lng]).addTo(map)
} else {
marker.setLatLng([lat, lng])
}
@@ -95,7 +107,7 @@ const updateLocation = (lat: number, lng: number, zoomTo = false) => {
}
onMounted(() => {
// Map logic is handled by ClientOnly placeholder if needed, but we initialize here
void initMap()
})
onUnmounted(() => {
@@ -186,10 +198,10 @@ watch(() => form.value.category_id, () => {
// Sincronizza input manuali con la mappa
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 = L.marker([newLat, newLng]).addTo(map)
marker = leaflet.marker([newLat, newLng]).addTo(map)
} else {
marker.setLatLng([newLat, newLng])
}
@@ -382,4 +394,3 @@ textarea {