` : ''; const loc = [s.city, s.country].filter(Boolean).join(', '); return `
${img}
${s.name||''}
${loc}
Voir la boutique →
`; } function renderMarkers(shops){ if(clusterer){ clusterer.clearMarkers(); } allMarkers.forEach(m => m.setMap(null)); allMarkers = []; const bounds = new google.maps.LatLngBounds(); const info = new google.maps.InfoWindow(); shops.forEach(s => { if(typeof s.lat !== 'number' || typeof s.lng !== 'number') return; const marker = new google.maps.Marker({ position: {lat:s.lat, lng:s.lng} }); marker.addListener('click', ()=>{ info.setContent(shopInfoHTML(s)); info.open(map, marker); }); allMarkers.push(marker); bounds.extend(marker.getPosition()); }); clusterer = new markerClusterer.MarkerClusterer({ map, markers: allMarkers }); if(!bounds.isEmpty()) map.fitBounds(bounds, { top:60, right:60, bottom:60, left:60 }); } async function fetchShops(){ const res = await fetch(SHOPS_ENDPOINT, { credentials:'same-origin' }); if(!res.ok) throw new Error('Failed to load shops'); return await res.json(); } function setupSearch(){ const input = document.getElementById('gmSearch'); if(!input) return; input.addEventListener('input', e => { const q = (e.target.value||'').toLowerCase(); const filtered = !q ? allShops : allShops.filter(s => (s.name||'').toLowerCase().includes(q) || (s.city||'').toLowerCase().includes(q) || (s.country||'').toLowerCase().includes(q) || (s.category||'').toLowerCase().includes(q) ); renderMarkers(filtered); }); } function setupLocate(){ const btn = document.getElementById('gmLocate'); if(!btn || !navigator.geolocation) return; btn.addEventListener('click', ()=>{ navigator.geolocation.getCurrentPosition(pos => { const { latitude, longitude } = pos.coords; map.panTo({lat: latitude, lng: longitude}); map.setZoom(10); }, ()=>{}, { enableHighAccuracy:true, timeout:5000 }); }); } function injectJSONLD(shops){ if(!shops || !shops.length) return; const items = shops.slice(0,100).map((s,i)=>({ "@type":"ListItem","position":i+1,"url":window.location.origin + "/shop/" + (s.slug||'').toLowerCase() + "/" })); const ld = {"@context":"https://schema.org","@type":"ItemList","name":"Pigee Shops Map","itemListElement":items}; const script = document.createElement('script'); script.type='application/ld+json'; script.textContent=JSON.stringify(ld); document.body.appendChild(script); } async function init(){ initMap(); try{ allShops = await fetchShops(); renderMarkers(allShops); setupSearch(); setupLocate(); injectJSONLD(allShops); }catch(e){ console.error(e); } } document.addEventListener('DOMContentLoaded', init); })();
🚀 SEO par Pigee