How to Integrate Google Maps in CakePHP 5 (Step-by-Step Guide)
Learn how to integrate Google Maps in CakePHP 5 application with step-by-step guide, database integration, and multiple markers display.
Google Maps is one of the most powerful and widely used tools to display locations and directions on a website. If you are building a business directory, store locator, travel listing, or logistics app, integrating Google Maps can make your web application more user-friendly and interactive.
In this tutorial, we’ll go step-by-step on how to integrate Google Maps in your CakePHP 5 project. We’ll start with a simple single-point map and then move towards fetching multiple location points from a database and displaying them dynamically.
1. Prerequisites
Before we begin, make sure you have:
- CakePHP 5 project already set up
- Basic knowledge of PHP and MVC architecture
- A valid Google Maps API key (we’ll cover how to get it below)
2. Get Your Google Maps API Key
To use Google Maps on your website, you need an API key from Google Cloud Console. Here’s how you can get one:
- Visit Google Cloud Console
- Create a new project or select an existing one.
- Go to APIs & Services → Credentials.
- Click on Create Credentials → API key.
- Copy the generated API key and keep it safe. It will look something like this:
AIzaSyD-EXAMPLE-KEY1234567890abcdefghi - Enable Maps JavaScript API and Geocoding API for your project.
- Restrict your key by domain or IP for security.
Note: Billing must be enabled on your Google Cloud project, but Google offers a free usage quota that’s enough for most small projects.
3. Create the Controller
Create src/Controller/MapsController.php with the following code:
<?php
namespace App\Controller;
use App\Controller\AppController;
class MapsController extends AppController
{
public function index()
{
// Default location - Center of India (Nagpur region)
$defaultLocation = [
'lat' => 21.146633,
'lng' => 79.088860,
'title' => 'Center of India'
];
$this->set(compact('defaultLocation'));
}
}
This sends the location details to the view.
4. Define the Route
Edit config/routes.php:
use Cake\Routing\Router;
Router::scope('/', function ($routes) {
$routes->connect('/map', ['controller' => 'Maps', 'action' => 'index']);
$routes->fallbacks();
});
Now visit your map at: http://localhost:8765/map
5. Create the View File
Create templates/Maps/index.php:
<!DOCTYPE html>
<html>
<head>
<title>Google Map Integration in CakePHP 5</title>
<style>
#map {
height: 450px;
width: 100%;
border-radius: 8px;
}
</style>
</head>
<body>
<h2>Google Map Integration in CakePHP 5</h2>
<div id="map"></div>
<script>
function initMap() {
const location = <?= json_encode($defaultLocation) ?>;
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 6,
center: { lat: location.lat, lng: location.lng },
});
const marker = new google.maps.Marker({
position: { lat: location.lat, lng: location.lng },
map: map,
title: location.title,
});
}
</script>
<!-- Replace YOUR_API_KEY with your real Google Maps key -->
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" async defer></script>
</body>
</html>
6. Run and Test
Start your local server: bin/cake server Then open: http://localhost:8765/map. You’ll see a map centered in the middle of India (Nagpur area) with one marker.

Tip: During the development if you don't have the API_KEY, then simply remove the key param from the URL just like below:
<script src="https://maps.googleapis.com/maps/api/js?callback=initMap" async defer></script>
and it will show the map with warning "For development purpose only" On production application, you must have to include your API_KEY.
7. Customizing Your Map
Once your map is working, you can start customizing it to match your project requirements. Below are some of the most useful customization options for real-world applications.
Adding Multiple Markers
You can pass multiple marker locations from the controller:
public function index()
{
$markers = [
['lat' => 21.146633, 'lng' => 79.088860, 'title' => 'Nagpur'],
['lat' => 19.076090, 'lng' => 72.877426, 'title' => 'Mumbai'],
['lat' => 28.613939, 'lng' => 77.209023, 'title' => 'Delhi'],
];
$this->set(compact('markers'));
}
Then update your JavaScript to loop through each location:
function initMap() {
const markers = <?= json_encode($markers) ?>;
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 5,
center: { lat: 22.5, lng: 78.9 },
});
markers.forEach(point => {
new google.maps.Marker({
position: { lat: point.lat, lng: point.lng },
map: map,
title: point.title
});
});
}
Adding Info Windows (Popups)
Show information when a marker is clicked:
const marker = new google.maps.Marker({ position, map, title });
const infoWindow = new google.maps.InfoWindow({
content: `<b>${point.title}</b><br>Latitude: ${point.lat}<br>Longitude: ${point.lng}`
});
marker.addListener('click', () => {
infoWindow.open(map, marker);
});
This is great for displaying store details, contact info, or status.
Using Custom Marker Icons
Replace the default red pin with a custom icon or logo:
new google.maps.Marker({
position,
map,
icon: "https://maps.google.com/mapfiles/ms/icons/blue-dot.png",
});
You can use PNG, SVG, or even animated icons depending on your design.
Map Styles and Themes
Customize the map appearance using Styled Maps — perfect for dark mode or branded websites. Example dark theme:
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 5,
center: { lat: 22.5, lng: 78.9 },
styles: [
{ elementType: "geometry", stylers: [{ color: "#242f3e" }] },
{ elementType: "labels.text.stroke", stylers: [{ color: "#242f3e" }] },
{ elementType: "labels.text.fill", stylers: [{ color: "#746855" }] },
]
});
You can find free JSON style themes on Snazzy Maps
Capturing User Clicks on Map
Allow users to pick locations (useful for address forms):
map.addListener("click", (event) => {
const clickedLat = event.latLng.lat();
const clickedLng = event.latLng.lng();
console.log("Clicked:", clickedLat, clickedLng);
});
You can save these coordinates to the database via AJAX or form submission.
Responsive and Mobile-Friendly Map
Use flexible CSS to make your map adapt to all devices:
#map {
width: 100%;
height: 60vh;
border-radius: 10px;
}
This ensures the map looks great on mobile, tablet, and desktop.
Loading Marker Data from Database (Dynamic Map)
In real projects, your locations are usually stored in a database table — for example, locations with columns: id, name, latitude, longitude, and description.
Let’s see how to fetch and display them dynamically.
Create Database Table for Storing Locations
Let’s create a table to store our location data. Run the below SQL command in your database:
CREATE TABLE locations (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
latitude DECIMAL(10,8),
longitude DECIMAL(11,8),
description TEXT
);
Now, insert some sample records:
INSERT INTO locations (name, latitude, longitude, description) VALUES
('Nagpur Central Park', 21.14580000, 79.08820000, 'Located in the heart of India, known as the Zero Mile City.'),
('Bhopal Lake View', 23.25990000, 77.41260000, 'Beautiful view of Upper Lake in Bhopal.'),
('Indore City Center', 22.71960000, 75.85770000, 'Commercial and cultural hub of Madhya Pradesh.'),
('Raipur Junction', 21.25140000, 81.62960000, 'Capital of Chhattisgarh with growing industrial area.'),
('Jabalpur Marble Rocks', 23.18150000, 79.98640000, 'Famous for scenic Marble Rocks and Dhuandhar Falls.');
Create the Model
CakePHP automatically detects the model if you have src/Model/Table/LocationsTable.php. If not, create one using Bake: bin/cake bake model Locations
Fetch Data in Controller
use Cake\ORM\TableRegistry;
public function index()
{
$locationsTable = TableRegistry::getTableLocator()->get('Locations');
$markers = $locationsTable->find()
->select(['latitude', 'longitude', 'name', 'description'])
->toArray();
$this->set(compact('markers'));
}
Display on Map (View)
function initMap() {
const markers = <?= json_encode($markers) ?>;
const map = new google.maps.Map(document.getElementById("map"), {
zoom: 5,
center: { lat: 22.5, lng: 78.9 },
});
markers.forEach(point => {
const position = { lat: parseFloat(point.latitude), lng: parseFloat(point.longitude) };
const marker = new google.maps.Marker({
position,
map,
title: point.name,
});
const infoWindow = new google.maps.InfoWindow({
content: `<b>${point.name}</b><br>${point.description}`
});
marker.addListener('click', () => {
infoWindow.open(map, marker);
});
});
}

This approach automatically plots all locations from your database — ideal for:
- Store locators
- Dealer or branch networks
- Event maps
- Travel or delivery tracking dashboards
Pro Tip:You can optimize large datasets using marker clustering libraries like @googlemaps/markerclusterer
Common Troubleshooting Tips
- If the map doesn’t load, check your API key and make sure it’s active and unrestricted for localhost or your domain.
- Ensure the JavaScript file URL includes your correct API key.
- Use browser console (
F12 → Console) to check for any API-related errors. - Always clear your browser cache after making code changes.
Final Thoughts
Integrating Google Maps in CakePHP 5 is quite straightforward. Once you have the basic setup, you can easily extend it with real-time tracking, geocoding, or distance calculations. Whether you’re building a travel portal, logistics app, or local directory, this feature adds both functionality and visual appeal.
With CakePHP’s MVC structure, keeping the logic separated from presentation is easy — making your code clean, scalable, and easy to maintain.