-
-
Notifications
You must be signed in to change notification settings - Fork 536
Leaflet Maps Integration
ChurchCRM 7.0.0 replaced Google Maps / Bing Maps with Leaflet.js + OpenStreetMap. No API key is required. This guide covers how to embed interactive maps in ChurchCRM pages and plugins.
Before 7.0.0, maps required a Google Maps API key (sGoogleMapsRenderKey) and a Bing Maps key (sBingMapKey). Both are now removed. Maps work out of the box using:
-
Tiles: OpenStreetMap via
tile.openstreetmap.org -
Geocoding: Nominatim (
nominatim.openstreetmap.org) - Map renderer: Leaflet.js (already bundled in the frontend build)
Leaflet.js is bundled in ChurchCRM's frontend build. It is available globally as L on any page that includes the standard footer.
<?php require SystemURLs::getDocumentRoot() . '/Include/Footer.php'; ?>
<!-- Leaflet is already loaded by Footer.php -->If your page does not use the standard footer, add:
<link rel="stylesheet" href="<?= SystemURLs::getRootPath() ?>/skin/css/leaflet.min.css">
<script src="<?= SystemURLs::getRootPath() ?>/skin/js/leaflet.min.js"></script><!-- Map container -->
<div id="map" style="height: 400px; width: 100%;"></div>
<script>
document.addEventListener('DOMContentLoaded', function () {
const map = L.map('map').setView([<?= $lat ?>, <?= $lng ?>], 13);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// Add a marker
L.marker([<?= $lat ?>, <?= $lng ?>])
.addTo(map)
.bindPopup('<?= addslashes($label) ?>')
.openPopup();
});
</script><div id="map" style="height: 500px;"></div>
<script>
document.addEventListener('DOMContentLoaded', function () {
const map = L.map('map').setView([<?= $churchLat ?>, <?= $churchLng ?>], 11);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
const families = <?= json_encode($familiesData) ?>;
families.forEach(function (family) {
if (family.lat && family.lng) {
L.marker([family.lat, family.lng])
.addTo(map)
.bindPopup(family.name);
}
});
});
</script>Where $familiesData is a PHP array of objects with lat, lng, and name fields.
Use the Geocoder service class, which calls Nominatim:
use ChurchCRM\Service\GeocoderService;
$geocoder = new GeocoderService();
$result = $geocoder->geocodeAddress('123 Main St', 'Springfield', 'IL', '62701', 'US');
if ($result !== null) {
$lat = $result->getLatitude();
$lng = $result->getLongitude();
}Do not call Nominatim directly from JavaScript — rate-limiting and CORS restrictions apply. Always geocode server-side.
Nominatim's usage policy limits requests to approximately 1 per second. ChurchCRM's geocoder automatically respects this limit with a small delay between requests during bulk operations (e.g., "Update All Family Coordinates"). Do not parallelize geocoding requests.
For large installations (tens of thousands of records), consider running a self-hosted Nominatim instance.
Plugins can embed maps on their custom pages using the same approach as core pages. Ensure:
- Your plugin page includes the standard ChurchCRM footer (which loads Leaflet)
- Your map container has a defined height (Leaflet requires a fixed height to render)
- You read coordinates from the Propel ORM models (e.g.,
Family::getLatitude(),Family::getLongitude())
| Symptom | Likely cause | Fix |
|---|---|---|
| Map container is blank | Leaflet initialized before container is in DOM | Move L.map() call inside DOMContentLoaded
|
| Tiles load but map is gray | Container has no height | Set height: 400px (or any value) on the container |
| Tiles don't load | Server can't reach tile.openstreetmap.org
|
Check outbound HTTPS; verify DNS from server |
| Marker at 0,0 (ocean) |
null lat/lng passed to Leaflet |
Guard with if (lat && lng) before placing marker |
| Geocoding returns null | Nominatim can't parse the address | Clean the address — spell out abbreviations, add country |
- Geographic utilities documentation — user docs for the map view
- Maps & Geocoding documentation — admin docs for maps configuration
- Tabler-UI-Components — general UI component reference
- Home
- Wiki → Docs links — User & admin manuals moved to docs.churchcrm.io
→ docs.churchcrm.io for installation & setup
- Installation ← Start here!
- First Run Setup
- Features Overview
→ docs.churchcrm.io for user manuals
- User Guide (docs)
- People Management — docs
- Groups & Events
- Tools
- Finances
→ docs.churchcrm.io for admin manuals
- User Management
- System Maintenance
- Configuration
- Troubleshooting
- Localization
Contributing to ChurchCRM
- Quick Start
- Testing & CI/CD
- Code & Architecture
- Localization
- Release & Security