Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Google Map Bundle Laravel Package

fungio/google-map-bundle

fungio/google-map-bundle is a Symfony bundle that simplifies embedding Google Maps in your templates. It offers configuration and Twig helpers for rendering maps, markers, and controls, letting you add interactive maps without repetitive JavaScript.

View on GitHub
Deep Wiki
Context7

Getting Started

This bundle is a Symfony 4 port of the long-deprecated Ivory/egeloen Google Map bundle. It gives you a PHP object graph (Map, Marker, InfoWindow, Polyline, Polygon, Circle, Coordinate) plus a Twig renderer that emits the Google Maps JavaScript API bootstrap code for you. You build the map server-side; the bundle prints the HTML/JS.

Install and register

composer require fungio/google-map-bundle

If Flex does not auto-register it, add it to config/bundles.php:

Fungio\GoogleMapBundle\FungioGoogleMapBundle::class => ['all' => true],

Configure the API key in config/packages/fungio_google_map.yaml (confirm the alias with bin/console config:dump-reference | grep -i map):

fungio_google_map:
    api_key: '%env(GOOGLE_MAPS_API_KEY)%'

First use case — one map, one marker

// src/Controller/StoreController.php
use Fungio\GoogleMap\Base\Coordinate;
use Fungio\GoogleMap\Map;
use Fungio\GoogleMap\Overlay\Marker;

public function show(Store $store)
{
    $map = new Map();
    $map->setCenter(new Coordinate($store->getLat(), $store->getLng()));
    $map->setZoom(14);
    $map->getOverlayManager()->addMarker(
        new Marker(new Coordinate($store->getLat(), $store->getLng()))
    );

    return $this->render('store/show.html.twig', ['map' => $map]);
}
{# templates/store/show.html.twig #}
{{ google_map(map) }}

Where to look first

  1. bin/console debug:container | grep -i map — service IDs are the fork's most likely deviation from upstream Ivory, and they are what you will inject.
  2. bin/console debug:twig | grep -i map — confirms the actual Twig function name (google_map, fungio_google_map, etc.).
  3. vendor/fungio/google-map-bundle/Resources/views/ — the base templates you will override for layout/styling.
  4. vendor/fungio/google-map-bundle/DependencyInjection/Configuration.php — the authoritative list of config keys, since documentation is thin.

Implementation Patterns

Inject a MapBuilder rather than new Map() in real code. It wires in your configured defaults and keeps the map configurable per environment:

public function __construct(private MapBuilderInterface $mapBuilder) {}

public function show(Store $store): Response
{
    $map = $this->mapBuilder->create();
    $map->setCenter(new Coordinate($store->getLat(), $store->getLng()));
    // ...
}

Loop entities into markers. The dominant pattern is: query a repository, iterate, add a marker per row, and attach an info window with rendered Twig HTML:

foreach ($stores as $store) {
    $marker = new Marker(new Coordinate($store->getLat(), $store->getLng()));

    $window = new InfoWindow();
    $window->setContent($this->renderView('store/_infowindow.html.twig', [
        'store' => $store,
    ]));
    $window->setAutoClose(false);

    $marker->setInfoWindow($window);
    $map->getOverlayManager()->addMarker($marker);
}

Keep info-window templates tiny — they are inlined as JS string literals, so quotes and newlines matter (see Gotchas).

Use a form type for coordinate pickers. For admin/edit screens, back the map with two hidden numeric inputs (lat, lng) and a marker whose draggable flag is on; the bundle's JS exposes the marker on the generated map object so a small inline script can write back into the form on dragend. This is far less work than wiring a full JS map component.

Multiple maps on one page. Each Map render produces a DOM id derived from the map instance. If you render the same Map object twice, you get duplicate ids and the second map breaks — always build a fresh Map per view or set an explicit unique id/HTML prefix on each.

Server-rendered vs. dynamic. This bundle is the right tool for maps that are fully determined at render time (store locators paginated server-side, static detail pages). For maps that need to update without a reload (filters, clustering that changes live), render the initial map through the bundle and mutate it with the JS API in an Encore entry that grabs the generated map instance — don't try to round-trip every overlay change through PHP.

Testing hook. Because output is deterministic HTML+JS, functional assertions are cheap:

$this->assertStringContainsString('"lat":48.8566', $client->getResponse()->getContent());
$this->assertSelectorExists('[data-google-map]');

Gotchas and Tips

Symfony 4 is EOL and the bundle's composer constraints reflect that. Before adopting, run composer why-not symfony/framework-bundle ^6.0 — you will almost certainly be pinned. If you need to move forward, plan to fork the bundle and widen the constraint (the code is small) or to replace it. With 2 stars and 0 dependents there is no upstream momentum to inherit.

URL-encode and restrict the key. The key is interpolated into the <script src="https://maps.googleapis.com/maps/api/js?key=..."> tag. If your key comes from an env var containing %, &, or +, the script silently fails with a console error and a grey canvas. Set HTTP-referrer restrictions in Google Cloud Console per environment, and use separate keys for dev/prod so a leaked dev key cannot burn the production quota.

The renderer emits a <script> tag, which fights with Encore. If you load scripts in defer or via encore_entry_script_tags, the generated inline map initialisation can run before the Maps SDK finishes loading. Either disable defer for that page or use the bundle's callback option so your init function is invoked after google.maps is ready.

Info-window content is embedded as a JS literal. Twig output containing </script>, unescaped quotes, or literal newlines will break the page. Keep the partial to plain markup and let the bundle's escaping do its job; if you need HTML, keep it short enough to spot-check in view-source.

Service IDs diverge from upstream Ivory. Documentation and Stack Overflow answers for egeloen/google-map-bundle reference ivory_google_map.*. This fork renames them. Always resolve via debug:container; never copy-paste a get('ivory_google_map...') call from a forum.

Debugging a blank map. In order: (1) check the browser console for RefererNotAllowedMapError / InvalidKeyMapError; (2) dump($map) before rendering to confirm center and overlays are actually populated; (3) check whether the overlay manager requires markers to be added before setCenter for auto-fit behaviour; (4) verify the map container has an explicit height — the bundle's default template often leaves it to your CSS, and a zero-height div renders nothing.

Extension points worth knowing. Custom overlay types implement the bundle's Overlay interface and register with the OverlayManager; for anything Google-specific that isn't modelled (advanced markers, custom tilesets) the pragmatic escape hatch is Map::setOptions([...]) / the raw libraries config key rather than fighting the object model. Service-level customisation is done by decorating MapBuilderInterface or the renderer service in config/services.yaml.

Budget a half-day for the audit. Low stars, zero dependents and a four-year-old Symfony target mean no security review has happened. Vendor-pin the package (composer.json with an exact version) and keep the map-building code behind an interface of your own so you can swap to a maintained alternative — or to the Maps JS API directly — without touching controllers.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle