W 2013 roku dodanie Mapy Google oznaczało wklejenie <iframe> z maps.google.com. Proste, szybkie, darmowe. W 2026 roku Google Maps to zaawansowana Platforma Chmurowa, która wymaga kluczy API, powiązanego konta rozliczeniowego, śledzi dane użytkowników i podlega rygorystycznym regulacjom prywatności (RODO/GDPR).
Jeśli po prostu wklejasz iframe, nie tylko robisz to źle - narażasz się na poważne konsekwencje finansowe i prawne. Niezabezpieczony klucz API może zostać ukradziony przez boty, generując tysiące dolarów opłat w ciągu godzin. Nieprawidłowa implementacja pod kątem RODO może skutkować karami administracyjnymi. A źle zoptymalizowana mapa może zniszczyć wyniki Core Web Vitals, obniżając pozycję w wyszukiwarce.
Ten przewodnik to kompleksowe źródło wiedzy dla deweloperów WordPress, którzy chcą zaimplementować Google Maps profesjonalnie. Omawiamy nie tylko techniczną integrację, ale także bezpieczeństwo API, optymalizację wydajności, zgodność z przepisami oraz wpływ na lokalne SEO. Niezależnie od tego, czy wybierzesz gotową wtyczkę, czy implementację customową - znajdziesz tu wszystko, czego potrzebujesz.
Dlaczego Google Maps jest kluczowe dla lokalnego SEO w 2026
W erze wyszukiwania generatywnego i AI Overviews, lokalne SEO stało się jeszcze ważniejsze. Google Maps to nie tylko wizualny element strony - to most łączący Twój biznes z ekosystemem Google.
Jak Google Maps wpływa na widoczność w wynikach lokalnych
Mapy Google są integralną częścią Google Local Pack - trzech wyników, które pojawiają się nad organicznymi wynikami wyszukiwania dla zapytań lokalnych.
Spójność danych między Twoją stroną WordPress a Google Maps jest krytyczna:
- NAP Consistency (Name, Address, Phone) - dokładnie te same dane na stronie, w mapie i w Profilu Google
- Strukturalne dane Schema.org - znaczniki LocalBusiness wzmacniają sygnały dla Google
- Osadzona mapa - potwierdza lokalizację fizyczną i zwiększa zaufanie
Problemy przy integracji Google Maps w 2026
W 2026 roku deweloperzy stoją przed nowymi wyzwaniami:
- Core Web Vitals - Google Maps domyślnie ładuje ~2MB JavaScriptu, co może zniszczyć wyniki LCP i INP
- Privacy-First Web - RODO, ePrivacy Directive i nowe regulacje wymagają jawnej zgody na ładowanie map
- API Costs - od marca 2025 każde SKU ma własny darmowy próg miesięczny zamiast wspólnego kredytu, a użycie trzeba monitorować
- Mobile-First - mapa musi działać na małych ekranach i przy obsłudze dotykiem, więc musi być responsywna
Czym Maps Embed API różni się od skopiowanego iframe
Iframe bywa dwojakiego rodzaju. Fragment kodu skopiowany z okna “Udostępnij” w google.com/maps nie ma klucza API ani umowy, więc nie stoi za nim żaden projekt, limit ani raport użycia. Maps Embed API to udokumentowana wersja tego samego pomysłu: iframe, którego src wskazuje na https://www.google.com/maps/embed/v1/MAP_MODE?key=YOUR_API_KEY&PARAMETERS, a tryb to jeden z place, view, directions, streetview lub search.
Na stronie o użyciu i rozliczeniach Google podaje, że Maps Embed API “jest darmowe w użyciu, bez limitu żądań” (tłumaczenie własne) i że nie ma limitów na sekundę ani na dzień. Każde żądanie nadal wymaga klucza API, więc opisane niżej ograniczenia klucza obowiązują także tutaj. Osadzone mapy nie są obsługiwane poniżej 200 px w żadnym wymiarze, a Google prosi o atrybut referrerpolicy na iframe, żeby przeglądarka wysłała Twoją domenę w nagłówku Referer. Bez niego klucz ograniczony do Twojej strony odrzuci żądanie.
<iframe
width="600" height="450" style="border:0" loading="lazy"
referrerpolicy="no-referrer-when-downgrade"
src="https://www.google.com/maps/embed/v1/place?key=YOUR_API_KEY&q=YOUR_ADDRESS">
</iframe>Embed API sprawdza się na stronie kontaktowej z jedną lokalizacją. Nie niesie ryzyka rozliczeniowego i nie wymaga pisania JavaScriptu. Natywne loading="lazy" na iframe trzyma mapę poza początkowym ładowaniem strony. Kwestia prywatności jednak nie znika. Iframe nadal ładuje treści z serwerów Google w przeglądarce odwiedzającego, więc zasady zgody z części tego poradnika o RODO dotyczą go tak samo jak JavaScript API. Gdy potrzebujesz własnych markerów, klastrowania, własnego stylu albo interakcji z resztą strony, właściwym narzędziem jest Maps JavaScript API.
Jak uzyskać klucz API Google Maps
Zanim dodasz mapę do WordPressa, musisz skonfigurować Google Maps Platform. To proces wieloetapowy, który wymaga uwagi do szczegółów.
Krok 1: Tworzenie projektu w Google Cloud Console
- Przejdź do Google Cloud Console
- Kliknij selektor projektów (górna belka) i wybierz “New Project”
- Nadaj nazwę projektu (np. “WordPress Maps - TwojaFirma”)
- Wybierz organizację (opcjonalnie) i lokalizację
- Kliknij “Create”
Ważne: Projekt powinien mieć opisową nazwę - ułatwi to zarządzanie, gdy będziesz miał więcej projektów.
Krok 2: Włączanie wymaganych API
Google Maps Platform składa się z wielu osobnych API. Dla typowej strony WordPress potrzebujesz:
| API | Przeznaczenie | Darmowy próg miesięczny (model od marca 2025) |
|---|---|---|
| Maps JavaScript API | Interaktywne mapy na stronie | 10 000 załadowań mapy (Dynamic Maps, Essentials) |
| Geocoding API | Konwersja adresów na współrzędne | 10 000 zdarzeń (Essentials) |
| Places API | Autocomplete adresów, szczegóły miejsc | Legacy, nowe projekty korzystają z Places API (New), patrz cennik |
| Static Maps API | Statyczne obrazy map | 10 000 zdarzeń (Essentials) |
Ceny powyżej progu się zmieniają, aktualne znajdziesz w cenniku Google.
Aby włączyć API:
- W Cloud Console przejdź do “APIs & Services” i wybierz “Library”
- Wyszukaj “Maps JavaScript API”
- Kliknij “Enable”
- Powtórz dla innych potrzebnych API
Krok 3: Konfiguracja rozliczeń i limity budżetowe
Maps JavaScript API wymaga konta rozliczeniowego, nawet jeśli nigdy nie przekroczysz darmowego progu.
Konfiguracja billingu:
- Przejdź do “Billing” i wybierz “Manage billing accounts”
- Utwórz nowe konto rozliczeniowe lub wybierz istniejące
- Dodaj metodę płatności (karta kredytowa)
- Powiąż konto z projektem
Starsze poradniki, w tym wcześniejsze wersje tego, wspominają o miesięcznym kredycie 200 USD. Ten model już nie obowiązuje. Według strony Google o zmianach w rozliczeniach z marca 2025 (dostęp 2026-10-14) Google “zastąpiło comiesięczny kredyt w wysokości 200 USD darmowym miesięcznym progiem użycia dla każdego SKU z Core Services” (tłumaczenie własne). Każde SKU należy do kategorii (Essentials, Pro albo Enterprise), a darmowy próg zależy od kategorii.
W aktualnym cenniku SKU, z których korzysta typowa strona WordPress, są w kategorii Essentials: Dynamic Maps (jedno załadowanie mapy w Maps JavaScript API), Static Maps i Geocoding mają po 10 000 darmowych rozliczanych zdarzeń miesięcznie, a SKU Embed figuruje jako nielimitowane. Większość SKU Pro ma próg 5 000, a większość SKU Enterprise 1 000. Progi liczą się osobno dla każdego SKU, więc strona, która ładuje mapę dynamiczną i dodatkowo geokoduje adresy, korzysta z dwóch oddzielnych darmowych progów. Ceny powyżej progu zmieniają się w czasie, dlatego sprawdzaj je w cenniku, a nie we wpisie na blogu.
Budżet i limity zapytań: Przed niespodziewaną fakturą chronią dwa mechanizmy. Budżet w Cloud Billing wysyła alerty, gdy wydatki osiągną ustawione progi, ale nie zatrzymuje API. Limit (quota) w “APIs & Services” ogranicza liczbę żądań na minutę lub na dzień, a żądania ponad limit kończą się błędem. Dobre praktyki bezpieczeństwa API Google zalecają dla projektów działających po stronie klienta limity na minutę i na użytkownika. Ustaw limit powyżej realnego szczytu ruchu, bo po jego osiągnięciu błędy dostają też prawdziwi odwiedzający.
Ta sama strona z marca 2025 nadała status Legacy trzem usługom: Places API, Directions API i Distance Matrix API. Usługi Legacy nie dostają nowych funkcji, a strona o produktach legacy mówi, że “nie są dostępne w nowych projektach Cloud” (tłumaczenie własne). Projekt utworzony dziś musi korzystać z Places API (New) i Routes API, więc przykłady kodu wywołujące google.maps.places.Autocomplete lub DirectionsService mogą nie działać w nowym projekcie, choć nadal działają w starych.
Krok 4: Generowanie i zabezpieczanie klucza API
Klucz API to najważniejszy element bezpieczeństwa. Niezabezpieczony klucz może zostać ukradziony i użyty przez osoby trzecie, generując opłaty.
Generowanie klucza:
- Przejdź do “APIs & Services” i wybierz “Credentials”
- Kliknij “Create credentials” i wybierz “API key”
- Skopiuj wygenerowany klucz
Konfiguracja ograniczeń (obowiązkowa!):
- Application restrictions - wybierz “HTTP referrers (web sites)”
- Dodaj swoje domeny:
https://twojastrona.pl/* - API restrictions - wybierz “Restrict key”
- Zaznacz tylko te API, których używasz (np. Maps JavaScript API, Geocoding API)
Dodatkowe zabezpieczenia:
- IP restrictions - jeśli używasz serwera proxy, możesz ograniczyć klucz do konkretnych IP
- Quota limits - ustaw dzieńne limity zapytań w “Quotas”
Jak zabezpieczyć klucz API Google Maps
Bezpieczeństwo klucza API to nie tylko kwestia finansowa - to ochrona reputacji Twojej firmy.
Jak ograniczyć klucz API do domeny (HTTP referrers)
HTTP referrers pozwalają ograniczyć użycie klucza do konkretnych domen. To najważniejsze zabezpieczenie.
Poprawne wzorce referrerów:
*.twojastrona.pl/* # Wszystkie subdomeny
https://twojastrona.pl/* # Konkretna domena z HTTPSCzego unikać:
- Nie używaj
*(wildcard) bez domeny - pozwala to na użycie klucza z dowolnej strony - Nie dodawaj
http://bezhttps://- wymuszaj szyfrowane połączenia - Nie zapominaj o subdomenach www
Jak monitorować użycie klucza API Google Maps
Regularne monitorowanie pozwala wykryć nieautoryzowane użycie zanim wygeneruje duże koszty.
W Cloud Console:
- Przejdź do “APIs & Services” i wybierz “Dashboard”
- Analizuj wykresy użycia
- Zwracaj uwagę na nagłe skoki
Konfiguracja alertów:
- Ustaw alerty na nietypowe wzorce użycia
- Włącz powiadomienia email dla wszystkich zmian w projekcie
Co zrobić, gdy klucz API Google Maps wycieknie
W przypadku podejrzenia kradzieży klucza:
Natychmiastowa rotacja:
- Przejdź do “Credentials”
- Kliknij ikonę rotacji przy kluczu
- Nowy klucz zostanie wygenerowany
Analiza logów:
- Sprawdź “Metrics” w Cloud Console
- Zidentyfikuj źródło nieautoryzowanego ruchu
Wzmocnienie zabezpieczeń:
- Dodaj dodatkowe restrykcje IP
- Zmniejsz limity quota
Google Maps a RODO na stronie WordPress
Google Maps przetwarza dane osobowe użytkowników (IP, lokalizacja, zachowanie). Zgodnie z RODO, musisz uzyskać zgodę przed załadowaniem skryptu.
Podstawa prawna dla Google Maps według RODO
Na stronie z mapą Google spotykają się dwa odrębne zestawy przepisów. Dyrektywa ePrivacy (2002/58/WE, art. 5 ust. 3) wymaga zgody przed zapisaniem informacji na urządzeniu odwiedzającego lub odczytaniem ich z niego, chyba że jest to niezbędne do świadczenia usługi, której odwiedzający wyraźnie zażądał. RODO reguluje z kolei same dane osobowe, zaczynając od adresu IP, który ujawnia każde żądanie do serwerów Google.
Rolę właściciela strony rozstrzygnął Trybunał Sprawiedliwości UE w sprawie Fashion ID (C-40/17), w wyroku z 29 lipca 2019 r. Sprawa dotyczyła przycisku “Lubię to” Facebooka, ale uzasadnienie obejmuje każdą osadzoną treść podmiotu trzeciego: operator strony może być współadministratorem w zakresie zbierania danych odwiedzających i przekazywania ich temu podmiotowi, ale nie w zakresie tego, co ten podmiot robi z nimi później. Jeśli podstawą prawną jest zgoda, operator musi ją uzyskać dla tych operacji i poinformować odwiedzających w chwili zbierania danych.
Umowa Google wskazuje ten sam kierunek. W Google Maps Platform Terms of Service Google i klient przyjmują Controller-Controller Data Protection Terms, więc Google działa jako odrębny administrator danych, które wysyłają mu odwiedzający, a nie jako Twój podmiot przetwarzający. Warunki zobowiązują Cię też do przestrzegania przepisów o prywatności “dotyczących Usług, które zapisują pliki cookie na urządzeniach Użytkowników Końcowych i uzyskują do nich dostęp” (tłumaczenie własne). Jeśli adres Twojego konta rozliczeniowego znajduje się w Europejskim Obszarze Gospodarczym, korzystanie z usług regulują osobne EEA Terms of Service. Dla transferów do Stanów Zjednoczonych Komisja Europejska przyjęła 10 lipca 2023 r. decyzję stwierdzającą odpowiedni stopień ochrony w ramach EU-U.S. Data Privacy Framework. Obejmuje ona transfery do firm z USA certyfikowanych w tych ramach.
W praktyce oznacza to, że mapa ładuje się po zgodzie albo po kliknięciu wyraźnie opisanego placeholdera, polityka prywatności wymienia Google jako odbiorcę i linkuje do polityki prywatności Google, a narzędzie do zgód umieszcza mapę w kategorii, która ją blokuje. To informacja ogólna, a nie porada prawna. O podstawie prawnej dla Twojej strony decyduje inspektor ochrony danych albo prawnik.
Wymagane elementy polityki prywatności:
- Informacja o użyciu Google Maps Platform
- Cel przetwarzania (wyświetlanie map, lokalizacja)
- Podstawa prawna (zgoda użytkownika)
- Link do polityki prywatności Google
Jak obsłużyć zgodę cookies dla Google Maps
Najpopularniejsze rozwiązania do zarządzania zgodami w WordPress:
1. Cookiebot (Usercentrics):
// Nasłuchiwanie na zgodę marketingową
window.addEventListener('CookiebotOnAccept', function() {
if (Cookiebot.consent.marketing) {
loadGoogleMaps();
}
});2. Complianz:
// Integracja z Complianz
document.addEventListener('cmplzConsentCategoryChange', function(event) {
if (event.detail.marketing) {
loadGoogleMaps();
}
});3. Custom implementation:
// Sprawdzenie localStorage
function checkConsent() {
const consent = localStorage.getItem('cookie_consent');
return consent && JSON.parse(consent).marketing === true;
}Jak zablokować Google Maps do czasu zgody
Struktura HTML przed zgodą:
<div id="map-container" class="map-placeholder">
<div class="map-consent-overlay">
<p>Tutaj wyświetlana będzie mapa Google</p>
<p>Google przetwarza dane osobowe zgodnie z <a href="/pl/polityka-prywatnosci/">polityką prywatności</a></p>
<button onclick="acceptMarketingAndLoadMap()">
Zaakceptuj i pokaż mapę
</button>
</div>
</div>Ładowanie mapy po zgodzie:
function loadGoogleMaps() {
// Ukryj overlay
document.querySelector('.map-consent-overlay').style.display = 'none';
// Dynamiczne załadowanie skryptu
const script = document.createElement('script');
script.src = `https://maps.googleapis.com/maps/api/js?key=${API_KEY}&callback=initMap`;
script.async = true;
script.defer = true;
document.head.appendChild(script);
}Geolokalizacja a RODO
Jeśli używasz geolokalizacji użytkownika (przycisk “Moja lokalizacja”):
- Wymagana jest dodatkowa zgoda - warunki Google Maps Platform wymagają wyraźnej, uprzedniej i odwoływalnej zgody na pobranie lokalizacji
- Browser API - użyj
navigator.geolocationz obsługą błędów - Fallback - zawsze oferuj ręczne wprowadzenie lokalizacji
function getUserLocation() {
if (!navigator.geolocation) {
console.log('Geolokalizacja nie jest wspierana');
return;
}
navigator.geolocation.getCurrentPosition(
position => {
const { latitude, longitude } = position.coords;
centerMap(latitude, longitude);
},
error => {
console.error('Błąd geolokalizacji:', error);
// Fallback do domyślnej lokalizacji
}
);
}Jak przyspieszyć ładowanie Google Maps w WordPressie
Google Maps może znacząco obniżyć wyniki Core Web Vitals. Oto strategie optymalizacji.
Jak Google Maps wpływa na Core Web Vitals
| Metryka | Na co wpływa Maps API | Docelowy próg |
|---|---|---|
| LCP | Skrypty i kafelki mapy konkurują z główną treścią o łącze | < 2.5s |
| INP | Wykonywanie JavaScriptu w wątku głównym opóźnia reakcję na kliknięcia | < 200ms |
| TBT | Długie zadania podczas inicjalizacji mapy | < 200ms |
| CLS | Kontener bez stałej wysokości przesuwa układ, gdy pojawia się mapa | < 0.1 |
Strategia 1: Lazy loading z Intersection Observer
Nie ładuj mapy, dopóki nie jest widoczna w viewport:
const mapContainer = document.getElementById('map-container');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
loadGoogleMaps();
observer.unobserve(entry.target);
}
});
}, {
rootMargin: '100px', // Załaduj trochę przed pojawieniem się
threshold: 0.1
});
observer.observe(mapContainer);Strategia 2: Wzorzec fasady (facade pattern)
Zamiast ładować mapę od razu, pokaż statyczny obraz:
<div class="map-facade" onclick="loadRealMap()">
<img src="/images/map-static.avif"
alt="Mapa lokalizacji - kliknij, aby załadować interaktywną mapę"
loading="lazy"
width="800"
height="450">
<button class="load-map-btn">
🗺️ Załaduj interaktywną mapę
</button>
</div>Generowanie statycznego obrazu: Użyj Static Maps API do wygenerowania obrazu, który będzie placeholderem:
https://maps.googleapis.com/maps/api/staticmap?
center=52.2297,21.0122
&zoom=15
&size=800x450
&markers=color:red|52.2297,21.0122
&key=YOUR_API_KEYStrategia 3: Async/Defer i priorytetyzacja
<!-- Źle: blokujące ładowanie -->
<script src="https://maps.googleapis.com/maps/api/js?key=..."></script>
<!-- Dobrze: nieblokujące -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=...&callback=initMap">
</script>Strategia 4: Preconnect i DNS Prefetch
Przyspiesz połączenie z serwerami Google:
<head>
<link rel="preconnect" href="https://maps.googleapis.com">
<link rel="preconnect" href="https://maps.gstatic.com" crossorigin>
<link rel="dns-prefetch" href="https://maps.googleapis.com">
</head>Strategia 5: Optymalizacja markerów i elementów
Ogranicz liczbę elementów na mapie:
const mapOptions = {
disableDefaultUI: true, // Ukryj domyślne kontrolki
zoomControl: true, // Pokaż tylko zoom
mapTypeControl: false,
streetViewControl: false,
fullscreenControl: false,
gestureHandling: 'cooperative' // Lepsze UX na mobile
};Leaflet albo Mapbox zamiast Google Maps
Google Maps nie zawsze jest najlepszym wyborem. Rozważ alternatywy:
Porównanie Google Maps, OpenStreetMap, Mapbox i HERE
| Rozwiązanie | Cena | Prywatność | Wydajność | Funkcjonalność |
|---|---|---|---|---|
| Google Maps | Darmowy próg dla każdego SKU, patrz cennik | Wymaga zgody | ~2MB | Pełna |
| OpenStreetMap + Leaflet | Darmowe | Prywatne | ~150KB | Podstawowa |
| Mapbox | 50,000 zdarzeń/mies. darmo | Wymaga zgody | ~300KB | Zaawansowana |
| HERE Maps | Freemium | Wymaga zgody | ~400KB | Zaawansowana |
| Mapy Apple | Darmowe (tylko Apple) | Prywatne | Zmienna | Ograniczona |
OpenStreetMap + Leaflet
Najlepsza darmowa alternatywa:
<!-- Leaflet CSS -->
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<!-- Leaflet JS -->
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<div id="osm-map" style="height: 400px;"></div>
<script>
const map = L.map('osm-map').setView([52.2297, 21.0122], 15);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
L.marker([52.2297, 21.0122]).addTo(map)
.bindPopup('Nasza lokalizacja')
.openPopup();
</script>Zalety:
- 100% darmowe
- Brak kluczy API
- Prywatne - nie wymaga zgody RODO
- Lekkie (~150KB)
Wady:
- Mniej dokładne dane
- Brak Street View
- Ograniczone funkcje premium
Mapbox
Zaawansowana alternatywa z lepszą wydajnością:
mapboxgl.accessToken = 'YOUR_MAPBOX_TOKEN';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [21.0122, 52.2297],
zoom: 15
});
new mapboxgl.Marker()
.setLngLat([21.0122, 52.2297])
.addTo(map);Zalety:
- Lepsza wydajność niż Google
- Zaawansowane style wizualne
- Dobre API dla deweloperów
Wady:
- Wymaga zgody RODO
- Płatne po przekroczeniu limitu
- Mniej rozpoznawalny przez użytkowników
Kiedy wybrać alternatywę dla Google Maps
- OSM + Leaflet: Proste mapy, ograniczony budżet, priorytet prywatności
- Mapbox: Zaawansowane style, lepsza wydajność, aplikacje mobilne
- Google Maps: Pełna funkcjonalność, Street View, integracja z Google ecosystem
Jak zmienić styl mapy Google na stronie
Domyślny wygląd Google Maps może nie pasować do Twojego brandu. Możesz dostosować style na kilka sposobów.
Jak stylować mapę przez Map ID w Cloud Console
Nowoczesny sposób zarządzania stylami:
- Przejdź do Google Cloud Console i wybierz “Map Styles”
- Kliknij “Create style”
- Użyj wizualnego edytora lub zaimportuj JSON
- Połącz styl z Map ID
- Użyj Map ID w kodzie:
const map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 52.2297, lng: 21.0122 },
zoom: 15,
mapId: 'YOUR_MAP_ID' // Tutaj podajesz Map ID
});Zalety Map IDs:
- Aktualizacja stylu bez zmiany kodu
- Wiele stylów dla różnych stron
- Wersjonowanie stylów
Stylowanie mapy przez JSON (starsza metoda)
Dla starszych implementacji lub zaawansowanej kontroli:
const mapStyles = [
{
featureType: 'poi.business',
stylers: [{ visibility: 'off' }] // Ukryj firmy konkurencji
},
{
featureType: 'transit',
elementType: 'labels.icon',
stylers: [{ visibility: 'off' }] // Ukryj ikony transportu
},
{
featureType: 'water',
elementType: 'geometry',
stylers: [{ color: '#e9e9e9' }] // Dostosuj kolor wody
},
{
featureType: 'landscape',
elementType: 'geometry',
stylers: [{ color: '#f5f5f5' }] // Dostosuj kolor tła
}
];
const map = new google.maps.Map(document.getElementById('map'), {
center: { lat: 52.2297, lng: 21.0122 },
zoom: 15,
styles: mapStyles
});Ciemny motyw mapy Google i kolory marki
Przykład stylu Dark Mode:
const darkModeStyles = [
{ elementType: 'geometry', stylers: [{ color: '#242f3e' }] },
{ elementType: 'labels.text.stroke', stylers: [{ color: '#242f3e' }] },
{ elementType: 'labels.text.fill', stylers: [{ color: '#746855' }] },
{
featureType: 'administrative.locality',
elementType: 'labels.text.fill',
stylers: [{ color: '#d59563' }]
},
{
featureType: 'poi',
elementType: 'labels.text.fill',
stylers: [{ color: '#d59563' }]
},
{
featureType: 'road',
elementType: 'geometry',
stylers: [{ color: '#38414e' }]
}
];Jak zmienić ikonę markera w Google Maps
Zastąp domyślne pinezki własnymi:
const marker = new google.maps.Marker({
position: { lat: 52.2297, lng: 21.0122 },
map: map,
icon: {
url: '/images/custom-marker.svg',
scaledSize: new google.maps.Size(40, 40),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(20, 40)
},
title: 'Nasza siedziba'
});Wskazówki dla markerów:
- Używaj formatu SVG dla skalowalności
- Zoptymalizuj rozmiar (zalecane 40x40px)
- Dodaj
titledla dostępności - Przygotuj wersję @2x dla wyświetlaczy Retina
Według listy wycofanych funkcji Google google.maps.Marker jest przestarzały od lutego 2024, a jego następcą jest google.maps.marker.AdvancedMarkerElement. Przykłady w tym poradniku używają starej klasy, która nadal działa, ale nowe funkcje trafiają tylko do zaawansowanych markerów, a te wymagają Map ID.
Wiele markerów i clustering w Google Maps
Dla stron z wieloma lokalizacjami (sieci sklepów, biur) potrzebujesz zaawansowanego zarządzania markerami.
Jak dodać wiele markerów na mapie Google
const locations = [
{ lat: 52.2297, lng: 21.0122, title: 'Siedziba główna' },
{ lat: 52.2300, lng: 21.0150, title: 'Oddział centrum' },
{ lat: 52.2280, lng: 21.0100, title: 'Magazyn' }
];
const markers = locations.map(location => {
return new google.maps.Marker({
position: { lat: location.lat, lng: location.lng },
map: map,
title: location.title
});
});Grupowanie markerów (Marker Clustering)
Gdy markerów jest dużo, użyj biblioteki MarkerClusterer:
<script src="https://unpkg.com/@googlemaps/markerclusterer/dist/index.min.js"></script>import { MarkerClusterer } from '@googlemaps/markerclusterer';
// Utwórz markery
const markers = locations.map(location => {
return new google.maps.Marker({
position: { lat: location.lat, lng: location.lng }
});
});
// Dodaj clustering
const clusterer = new MarkerClusterer({
map,
markers,
renderer: {
render: ({ count, position }) => {
return new google.maps.Marker({
position,
label: { text: String(count), color: 'white' },
icon: {
path: google.maps.SymbolPath.CIRCLE,
scale: 20,
fillColor: '#4285F4',
fillOpacity: 0.9,
strokeWeight: 2,
strokeColor: '#ffffff'
}
});
}
}
});Okna informacyjne markerów (Info Windows)
Dodaj informację o lokalizacji:
const infoWindow = new google.maps.InfoWindow();
markers.forEach(marker => {
marker.addListener('click', () => {
const content = `
<div class="map-info-window">
<h3>${marker.title}</h3>
<p>Adres: ul. Przykładowa 123</p>
<a href="https://www.google.com/maps/dir/?api=1&destination=${marker.position.lat()},${marker.position.lng()}"
target="_blank">Wyznacz trasę</a>
</div>
`;
infoWindow.setContent(content);
infoWindow.open(map, marker);
});
});Jak filtrować markery po kategorii
Dla zaawansowanych zastosowań (np. filtruj sklepy po kategorii):
function filterMarkers(category) {
markers.forEach(marker => {
const isVisible = category === 'all' || marker.category === category;
marker.setVisible(isVisible);
});
// Aktualizuj clustering
clusterer.clearMarkers();
const visibleMarkers = markers.filter(m => m.getVisible());
clusterer.addMarkers(visibleMarkers);
}
// Użycie
document.getElementById('filter-restaurants').addEventListener('click', () => {
filterMarkers('restaurant');
});Wyszukiwanie miejsc, trasa i Street View na mapie
Google Maps oferuje wiele funkcji interaktywnych, które mogą wzbogacić UX.
Wyszukiwanie miejsc (Places Autocomplete)
Dodaj autocomplete do formularzy adresowych:
<input type="text" id="address-input" placeholder="Wpisz adres...">const autocomplete = new google.maps.places.Autocomplete(
document.getElementById('address-input'),
{
types: ['address'],
componentRestrictions: { country: 'pl' } // Ogranicz do Polski
}
);
autocomplete.addListener('place_changed', () => {
const place = autocomplete.getPlace();
if (!place.geometry) {
console.log('Nie znaleziono lokalizacji');
return;
}
// Wyodrębnij komponenty adresu
const addressComponents = {
street: place.address_components.find(c => c.types.includes('route'))?.long_name,
number: place.address_components.find(c => c.types.includes('street_number'))?.long_name,
city: place.address_components.find(c => c.types.includes('locality'))?.long_name,
postal: place.address_components.find(c => c.types.includes('postal_code'))?.long_name
};
console.log('Wybrany adres:', addressComponents);
});Wyznaczanie trasy (Directions)
Pozwól użytkownikom wyznaczyć trasę do Twojej lokalizacji:
const directionsService = new google.maps.DirectionsService();
const directionsRenderer = new google.maps.DirectionsRenderer();
directionsRenderer.setMap(map);
function calculateRoute(origin) {
const request = {
origin: origin,
destination: { lat: 52.2297, lng: 21.0122 }, // Twoja lokalizacja
travelMode: google.maps.TravelMode.DRIVING,
provideRouteAlternatives: true
};
directionsService.route(request, (result, status) => {
if (status === 'OK') {
directionsRenderer.setDirections(result);
} else {
console.error('Błąd wyznaczania trasy:', status);
}
});
}
// Użycie z geolokalizacją
document.getElementById('get-directions').addEventListener('click', () => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
position => {
const origin = `${position.coords.latitude},${position.coords.longitude}`;
calculateRoute(origin);
},
() => {
// Fallback: poproś o ręczne wpisanie
const origin = prompt('Wpisz adres początkowy:');
if (origin) calculateRoute(origin);
}
);
}
});Street View
Dodaj podgląd Street View:
const panorama = new google.maps.StreetViewPanorama(
document.getElementById('street-view'),
{
position: { lat: 52.2297, lng: 21.0122 },
pov: {
heading: 34,
pitch: 10
},
zoom: 1
}
);
map.setStreetView(panorama);Jak zamienić adres na współrzędne (geokodowanie)
Konwertuj adresy tekstowe na współrzędne:
const geocoder = new google.maps.Geocoder();
function geocodeAddress(address) {
geocoder.geocode({ address: address }, (results, status) => {
if (status === 'OK') {
const location = results[0].geometry.location;
map.setCenter(location);
new google.maps.Marker({
map: map,
position: location
});
console.log('Współrzędne:', location.lat(), location.lng());
} else {
console.error('Geokodowanie nie powiodło się:', status);
}
});
}
// Użycie
geocodeAddress('Pałac Kultury i Nauki, Warszawa');Najlepsza wtyczka Google Maps do WordPressa
Jeśli nie chcesz implementować mapy samodzielnie, wybierz jedną z popularnych wtyczek.
WP Go Maps (dawniej Google Maps Easy)
Najlepsza dla: Użytkowników bez umiejętności programistycznych
| Funkcja | Dostępność |
|---|---|
| Interfejs wizualny | ✅ Tak |
| Wiele markerów | ✅ Tak |
| Clustering | ✅ Pro |
| Custom style | ✅ Tak |
| RODO compliance | ✅ Tak |
| Cena | Darmowa / 39$ Pro |
Zalety:
- Intuicyjny interfejs
- Wbudowana obsługa RODO
- Wsparcie dla wielu map
Wady:
- Ograniczone możliwości w wersji darmowej
- Mniej elastyczna niż customowa implementacja
MapPress
Najlepsza dla: Blogerów i małych stron
| Funkcja | Dostępność |
|---|---|
| Automatyczne mapy z postów | ✅ Tak |
| Shortcodes | ✅ Tak |
| Responsywność | ✅ Tak |
| Custom markery | ✅ Pro |
| Cena | Darmowa / 39$ Pro |
Zalety:
- Automatyczne tworzenie map z custom fields
- Prosta integracja z postami
Wady:
- Mniej funkcji niż WP Go Maps
- Ograniczona dokumentacja
Intergeo
Najlepsza dla: Zaawansowanych użytkowników
| Funkcja | Dostępność |
|---|---|
| Wiele warstw | ✅ Tak |
| Import/Export | ✅ Tak |
| Custom overlays | ✅ Tak |
| AdSense integration | ✅ Tak |
| Cena | Darmowa |
Zalety:
- Darmowa z większością funkcji
- Zaawansowane opcje warstw
Wady:
- Mniej intuicyjna
- Rzadziej aktualizowana
Advanced Custom Fields + Map Field
Najlepsza dla: Deweloperów
Jeśli używasz ACF, możesz dodać pole mapy:
// functions.php
function my_acf_init() {
acf_update_setting('google_api_key', 'YOUR_API_KEY');
}
add_action('acf/init', 'my_acf_init');Zalety:
- Pełna kontrola nad wyświetlaniem
- Integracja z custom fields
- Brak dodatkowej wtyczki do map
Wady:
- Wymaga umiejętności programistycznych
- Samodzielna implementacja wyświetlania
Którą wtyczkę Google Maps wybrać
| Scenariusz | Rekomendacja |
|---|---|
| Prosta mapa, brak kodowania | WP Go Maps |
| Mapy w postach/blogu | MapPress |
| Zaawansowane funkcje, darmowe | Intergeo |
| Pełna kontrola, custom development | ACF + custom code |
Google Maps w WordPressie bez wtyczki
Dla pełnej kontroli i optymalizacji, zaimplementuj mapę samodzielnie.
Struktura plików
twój-motyw/
├── assets/
│ ├── js/
│ │ ├── maps-config.js # Konfiguracja API
│ │ ├── maps-loader.js # Lazy loading
│ │ └── maps-init.js # Inicjalizacja mapy
│ └── css/
│ └── maps.css # Style mapy
└── template-parts/
└── map-container.php # HTML mapyRejestracja i ładowanie skryptów
// functions.php
function enqueue_google_maps() {
// Nie ładujemy Google Maps od razu!
// Zamiast tego ładujemy nasz customowy loader
wp_enqueue_script(
'maps-loader',
get_template_directory_uri() . '/assets/js/maps-loader.js',
[],
'1.0.0',
true
);
// Przekazanie zmiennych do JS
wp_localize_script('maps-loader', 'mapsConfig', [
'apiKey' => get_option('google_maps_api_key'),
'mapId' => get_option('google_maps_map_id'),
'defaultLat' => 52.2297,
'defaultLng' => 21.0122,
'consentRequired' => true
]);
wp_enqueue_style(
'maps-styles',
get_template_directory_uri() . '/assets/css/maps.css'
);
}
add_action('wp_enqueue_scripts', 'enqueue_google_maps');Loader Google Maps z obsługą zgody RODO
// assets/js/maps-loader.js
(function() {
'use strict';
const config = window.mapsConfig || {};
let mapLoaded = false;
// Sprawdź zgodę
function hasConsent() {
// Integracja z Cookiebot
if (window.Cookiebot) {
return Cookiebot.consent && Cookiebot.consent.marketing;
}
// Integracja z Complianz
if (window.cmplz_consent) {
return cmplz_consent.marketing;
}
// Custom localStorage
const consent = localStorage.getItem('cookie_consent');
if (consent) {
return JSON.parse(consent).marketing === true;
}
return false;
}
// Załaduj Google Maps API
function loadGoogleMaps() {
if (mapLoaded) return;
mapLoaded = true;
const script = document.createElement('script');
script.src = `https://maps.googleapis.com/maps/api/js?key=${config.apiKey}&callback=initMap&loading=async`;
script.async = true;
script.defer = true;
document.head.appendChild(script);
}
// Inicjalizacja po załadowaniu API
window.initMap = function() {
const mapContainer = document.getElementById('custom-map');
if (!mapContainer) return;
const map = new google.maps.Map(mapContainer, {
center: { lat: config.defaultLat, lng: config.defaultLng },
zoom: 15,
mapId: config.mapId,
disableDefaultUI: true,
zoomControl: true
});
// Dodaj marker
new google.maps.Marker({
position: { lat: config.defaultLat, lng: config.defaultLng },
map: map,
title: 'Nasza lokalizacja'
});
};
// Lazy loading z Intersection Observer
function initLazyLoading() {
const mapContainer = document.getElementById('map-container');
if (!mapContainer) return;
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting && hasConsent()) {
loadGoogleMaps();
observer.unobserve(entry.target);
}
});
}, {
rootMargin: '100px',
threshold: 0.1
});
observer.observe(mapContainer);
}
// Obsługa przycisku zgody
document.addEventListener('click', function(e) {
if (e.target.matches('.load-map-btn')) {
e.preventDefault();
// Zapisz zgodę
localStorage.setItem('cookie_consent', JSON.stringify({
marketing: true,
timestamp: Date.now()
}));
loadGoogleMaps();
}
});
// Nasłuchiwanie na zmiany zgody
document.addEventListener('cookie_consent_updated', function(e) {
if (e.detail.marketing && !mapLoaded) {
loadGoogleMaps();
}
});
// Inicjalizacja
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initLazyLoading);
} else {
initLazyLoading();
}
})();Szablon HTML kontenera mapy
<!-- template-parts/map-container.php -->
<div id="map-container" class="map-wrapper">
<?php if (!isset($_COOKIE['cookie_consent_marketing'])) : ?>
<!-- Fasada przed zgodą -->
<div class="map-facade">
<img
src="<?php echo get_template_directory_uri(); ?>/assets/images/map-placeholder.avif"
alt="Mapa lokalizacji - kliknij, aby załadować"
loading="lazy"
width="800"
height="450"
>
<div class="map-overlay">
<h3>Zobacz naszą lokalizację</h3>
<p>Google Maps wymaga akceptacji plików cookies.</p>
<button class="load-map-btn btn btn-primary">
🗺️ Załaduj mapę
</button>
<p class="privacy-note">
<a href="/pl/polityka-prywatnosci/">Dowiedz się więcej o przetwarzaniu danych</a>
</p>
</div>
</div>
<?php endif; ?>
<!-- Kontener na mapę -->
<div id="custom-map" style="height: 400px; width: 100%;"></div>
</div>Style CSS kontenera mapy
/* assets/css/maps.css */
.map-wrapper {
position: relative;
width: 100%;
border-radius: 8px;
overflow: hidden;
}
.map-facade {
position: relative;
cursor: pointer;
}
.map-facade img {
width: 100%;
height: auto;
display: block;
}
.map-overlay {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(255, 255, 255, 0.95);
padding: 2rem;
border-radius: 8px;
text-align: center;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}
.map-overlay h3 {
margin: 0 0 0.5rem;
font-size: 1.25rem;
}
.map-overlay p {
margin: 0 0 1rem;
color: #666;
}
.privacy-note {
font-size: 0.875rem;
margin-top: 1rem;
}
.privacy-note a {
color: #4285F4;
}
#custom-map {
min-height: 400px;
}
/* Responsywność */
@media (max-width: 768px) {
.map-overlay {
padding: 1rem;
width: 90%;
}
#custom-map {
min-height: 300px;
}
}Google Maps nie działa na stronie WordPress
Najczęstsze problemy i ich rozwiązania.
Błąd “This page can’t load Google Maps correctly”
Przyczyny:
- Brak klucza API lub nieprawidłowy klucz
- Brak aktywnego konta rozliczeniowego
- Ograniczenia HTTP referrer blokują domenę
Rozwiązania:
- Sprawdź, czy klucz jest poprawny w Cloud Console
- Upewnij się, że billing jest aktywny
- Dodaj swoją domenę do dozwolonych referrerów
Błąd “You must enable Billing”
Rozwiązanie:
- Przejdź do Cloud Console i wybierz Billing
- Utwórz lub wybierz konto rozliczeniowe
- Dodaj metodę płatności
- Powiąż konto z projektem
Mapa Google nie wyświetla się w WordPressie
Sprawdź:
- Czy kontener ma określoną wysokość?
- Czy skrypt Google Maps się załadował? (Network tab)
- Czy są błędy w konsoli JavaScript?
- Czy callback
initMapjest zdefiniowany?
Jak obniżyć wysokie opłaty za API Google Maps
Przyczyny i rozwiązania:
- Kradzież klucza - rotacja klucza, dodanie restrykcji IP
- Boty - implementacja reCAPTCHA, rate limiting
- Brak caching - cache wyników geokodowania
- Zbyt wiele zapytań - optymalizacja, lazy loading
Strona z mapą Google ładuje się wolno
Rozwiązania:
- Użyj lazy loading z Intersection Observer
- Zaimplementuj wzorzec fasady
- Dodaj
async deferdo skryptu - Użyj
preconnectdla domen Google
Geokodowanie Google Maps nie działa
Sprawdź:
- Czy Geocoding API jest włączone?
- Czy adres jest poprawny?
- Czy nie przekroczono limitów API?
// Dodaj obsługę błędów
geocoder.geocode({ address: address }, (results, status) => {
if (status === 'OK') {
// Sukces
} else if (status === 'ZERO_RESULTS') {
console.log('Nie znaleziono lokalizacji');
} else if (status === 'OVER_QUERY_LIMIT') {
console.log('Przekroczono limit zapytań');
} else {
console.error('Błąd geokodowania:', status);
}
});Podsumowanie
Integracja Google Maps z WordPressem w 2026 roku to znacznie więcej niż wklejenie kodu. To kompleksowy proces wymagający uwagi na:
- Bezpieczeństwo - zabezpieczenie klucza API przed kradzieżą
- Wydajność - lazy loading i optymalizacja pod Core Web Vitals
- Prywatność - obsługę wymagań RODO i zarządzanie zgodami
- UX - custom style i interaktywne funkcje
- SEO - spójność danych i strukturalne znaczniki
Niezależnie od tego, czy wybierzesz gotową wtyczkę, czy implementację customową - pamiętaj o najlepszych praktykach. Dobrze zaimplementowana mapa wspiera lokalne SEO i konwersję.
Nie pozwól, by mapa spowolniła Twoją stronę lub naraziła Cię na kary. Zbuduj to dobrze - raz, a porządnie.
Powiązane zasoby i dalsza lektura
Oficjalna dokumentacja
Narzędzia
WordPress
Optymalizacja wydajności
RODO i prywatność
Zobacz nasze usługi optymalizacji szybkości WordPress, jeśli chcesz poprawić Core Web Vitals i realną szybkość strony.







