ACF Google-Maps-Feld & Leaflet

Wie sich die komfortable Eingabemaske des ACF Google-Maps-Felds mit der schlanken, kostenlosen Kartenbibliothek Leaflet kombinieren lässt.

Verfasst am 31.07.2026

Für ein Projekt musste ich kürzlich mehrere Standorte auf einer Karte darstellen – klickbar, mit eigenem Marker-Icon und ohne dass die Website dafür von einem Google-Maps-API-Key abhängig wird. Die Lösung, mit der ich am zufriedensten bin, kombiniert zwei Dinge, die auf den ersten Blick nicht zusammengehören: das ACF Google-Maps-Feld für die Eingabe im Backend und Leaflet für die Darstellung im Frontend.

Was ist Leaflet?

Leaflet ist eine schlanke, quelloffene JavaScript-Bibliothek für interaktive Karten. Entwickelt wurde sie 2010/2011 vom ukrainischen Entwickler Volodymyr Agafonkin, ursprünglich bei CloudMade, mittlerweile als eigenständiges Open-Source-Projekt mit einer aktiven Community von Mitwirkenden weitergeführt.

Die Idee dahinter war von Anfang an bewusst minimalistisch: Statt eine der damals üblichen, schwerfälligen Mapping-Bibliotheken einzusetzen, wollte Agafonkin etwas Einfaches, Schnelles und Leichtes bauen. Das Ergebnis ist bis heute konsequent klein gehalten – die Bibliothek bringt nur rund 40 KB auf die Waage, und deckt trotzdem praktisch alles ab, was man für normale Kartenprojekte braucht: Marker, Popups, Zoom, verschiedene Kartenanbieter, GeoJSON-Daten und eine grosse Auswahl an Plugins für Spezialfälle.

Was Leaflet für mich zur bevorzugten Wahl macht:

  • Kein Vendor-Lock-in: Leaflet ist an keinen bestimmten Kartenanbieter gebunden. OpenStreetMap, Mapbox, eigene Tile-Server – alles ist möglich, ohne die Bibliothek zu wechseln.
  • Kein API-Key nötig, solange man mit offenen Kartenquellen wie OpenStreetMap arbeitet.
  • Sehr saubere, gut dokumentierte API, die sich auch ohne grosse Einarbeitung erschliesst.
  • Bewährt im grossen Massstab: Leaflet wird u. a. von Flickr, Foursquare, GitHub und der Washington Post eingesetzt. Für ein derart schlankes Projekt ein beachtliches Vertrauenssignal.
  • Wirklich Open Source, unter der BSD-2-Clause-Lizenz, ohne kommerzielle Einschränkungen.

Kurz gesagt: Leaflet macht genau das, was man von einer Kartenbibliothek erwartet – nicht mehr, nicht weniger – und das so unaufgeregt und zuverlässig, dass man schnell vergisst, dass im Hintergrund überhaupt eine Bibliothek läuft.
Kurz gesagt: Leaflet macht genau das, was man von einer Kartenbibliothek erwartet – nicht mehr, nicht weniger – und das so unaufgeregt und zuverlässig, dass man schnell vergisst, dass im Hintergrund überhaupt eine Bibliothek läuft.

Das Problem: Gute Backend-UX vs. gutes Frontend

Für Redaktorinnen und Redaktoren ist das ACF Google-Maps-Feld unschlagbar: Adresse eingeben, Pin auf der Karte verschieben, fertig. Niemand muss Koordinaten von Hand heraussuchen.

Im Frontend sieht die Sache anders aus. Wer dort ebenfalls Google Maps einbindet, handelt sich mehrere Dinge ein:

  • einen öffentlich sichtbaren API-Key, der eingeschränkt und überwacht werden muss
  • ein Kontingent, das bei viel Traffic Kosten verursacht
  • eine zusätzliche Diskussion rund um Datenschutz und Cookie-Einwilligung, weil Google-Dienste nachgeladen werden

Die Lösung: Das ACF-Feld bleibt, wo es am besten funktioniert, im Backend als Eingabehilfe. Im Frontend rendere ich die Karte stattdessen mit Leaflet.

Die Grundidee

Das ACF Google-Maps-Feld speichert im Hintergrund ganz normale Werte: lat, lng, address und ein paar weitere Angaben. Diese Werte lassen sich unabhängig von Google Maps auslesen und für eine beliebige Kartenbibliothek weiterverwenden. Google Maps wird also gar nie im Frontend genutzt, nur die Eingabemaske im Backend gehört Google, die Anzeige gehört Leaflet.

Umsetzung Schritt für Schritt

1. ACF-Feld anlegen

Im Feldgruppen-Editor ein Feld vom Typ Google Map anlegen, z. B. mit dem Namen standort.

 

2. Leaflet einbinden

Leaflet lade ich klassisch per CDN, zusammen mit meinen übrigen externen Bibliotheken in als enqueue-scripts:

function rho_enqueue_leaflet() {
    wp_enqueue_style( 'leaflet-css', 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css' );
    wp_enqueue_script( 'leaflet-js', 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js', array(), '1.9.4', true );
}
add_action( 'wp_enqueue_scripts', 'rho_enqueue_leaflet' );

 

3. Daten im flexible-Modul auslesen

In meiner flexible.php bekommt die Karte ihr eigenes Layout. Die ACF-Werte lese ich aus und übergebe sie als data-Attribute an den Karten-Container. So bleibt PHP und JavaScript sauber getrennt:

<?php if( have_rows('flexible') ): ?>
<?php while( have_rows('flexible') ): the_row() ?>
	<?php if( get_row_layout() == 'karte' ): ?>
		<?php $standort = get_sub_field('standort'); ?>
		<?php if( $standort ): ?>
		<section class="section-karte ">
			<div class="container ">
				<div id="rho-map"
					data-lat="<?php echo esc_attr( $standort['lat'] ); ?>"
					data-lng="<?php echo esc_attr( $standort['lng'] ); ?>"
					data-title="<?php echo esc_attr( get_the_title() ); ?>"
					data-address="<?php echo esc_attr( $standort['address'] ); ?>">
				</div>
			</div>
		</section>
		<?php endif; ?>
	<?php endif; ?>
<?php endwhile; ?>
<?php endif; ?>

 

4. Karte in script.js initialisieren

Da es sich um projektspezifische Logik handelt, gehört die Initialisierung in mein script.js:

document.addEventListener('DOMContentLoaded', function () {
	var mapEl = document.getElementById('rho-map');
	if (!mapEl) return;
	var lat = parseFloat(mapEl.dataset.lat);
	var lng = parseFloat(mapEl.dataset.lng);
	var map = L.map('rho-map').setView([lat, lng], 15);
	L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
		attribution: '&copy; OpenStreetMap-Mitwirkende'
	}).addTo(map);
	var icon = L.icon({
		iconUrl: '/wp-content/themes/mein-theme/img/marker.svg',
		iconSize: [32, 32],
		iconAnchor: [16, 32]
	});
	L.marker([lat, lng], { icon: icon })
		.addTo(map)
		.bindPopup('<strong>' + mapEl.dataset.title + '</strong><br>' + mapEl.dataset.address);
});

 

5. Etwas Grundstyling

Leaflet braucht zwingend eine Höhe für den Karten-Container, sonst bleibt sie unsichtbar. Das kommt bei mir wie gewohnt in die style.css:

#rho-map {
	width: 100%;
	height: 420px;
}

 

Mehrere Standorte auf einer Karte

Wer mehrere Standorte gleichzeitig anzeigen will, z. B. aus einem Custom Post Type, sammelt die ACF-Werte serverseitig in einem Array und gibt sie als JSON aus:

<?php
$standorte = array();
$posts = get_posts( array( 'post_type' => 'standorte', 'numberposts' => -1 ) );
foreach ( $posts as $post ) {
	$loc = get_field( 'standort', $post->ID );
	if ( $loc ) {
		$standorte[] = array(
			'lat'     => $loc['lat'],
			'lng'     => $loc['lng'],
			'title'   => get_the_title( $post->ID ),
			'address' => $loc['address'],
		);
	}
}
?>
<div id="rho-map-multi" data-standorte='<?php echo esc_attr( wp_json_encode( $standorte ) ); ?>'></div>

Im script.js wird daraus eine Schleife, die für jeden Standort einen Marker setzt – nach demselben Prinzip wie oben, einfach mit L.marker(…) pro Eintrag statt nur einmal.

Fazit

Man muss sich nicht zwischen guter Backend-UX und einer schlanken, kostenlosen Frontend-Lösung entscheiden. Das ACF Google-Maps-Feld liefert zuverlässig die Koordinaten – was danach mit ihnen passiert, entscheidet man selbst. Für die meisten Projekte reicht Leaflet mit OpenStreetMap-Kacheln völlig aus, ganz ohne API-Key, Kontingent oder zusätzliche Datenschutz-Diskussion.

Fragen und Antworten

Nein. Der API-Key wird nur für die Eingabemaske im WordPress-Backend benötigt (das ACF-Feld selbst). Im Frontend kommt ausschliesslich Leaflet mit OpenStreetMap zum Einsatz, dafür ist kein Key nötig.

Ja. Die Koordinaten mehrerer Beiträge lassen sich serverseitig sammeln und als JSON an die Karte übergeben. Im JavaScript wird daraus eine Schleife, die pro Standort einen Marker erzeugt.

Ja, Leaflet ist Open Source und kostenlos. Bei den OpenStreetMap-Standardkacheln gilt eine faire Nutzung; bei sehr viel Traffic lohnt sich ein alternativer, kostengünstiger Tile-Anbieter statt der öffentlichen OSM-Kacheln.

Ja, das empfiehlt sich. Beim Laden der Karte werden die Kartenkacheln direkt vom Server von OpenStreetMap abgerufen, wobei die IP-Adresse der Besucherin an diesen Drittanbieter übertragen wird. Eine IP-Adresse gilt als personenbezogenes Datum, weshalb ein kurzer Hinweis in der Datenschutzerklärung sinnvoll ist. Im Unterschied zu Google Maps setzt OpenStreetMap standardmässig keine Tracking-Cookies, weshalb in der Regel keine gesonderte Cookie-Einwilligung nötig ist. Für die rechtssichere Formulierung empfiehlt sich dennoch eine kurze Rücksprache mit einer Fachperson.