Integrations

WordPress & Drupal

How a CMS plugin connects a site to Mapsemble — the feed contract your plugin implements, and what each plan includes.

WordPress & Drupal

A CMS integration is one endpoint. Your site exposes its content as GeoJSON at a fixed path, Mapsemble calls that endpoint as visitors pan, filter and page, and nothing is ever copied out of your database.

CMS Feed path Starterkit
Drupal /mapsemble/features drupal-vanilla, drupal-store-locator
WordPress /wp-json/mapsemble/v1/features wordpress-vanilla

Pick the starterkit for your CMS when you create a map, enter your site URL, and the data source is wired for you.

What each plan includes

  • Free — build maps and share them at their hosted link.
  • Starter — embed a map on your own site (one licensed domain).
  • Pro — serve the map from your own feed, with remote filter options and CMS-rendered popups.

You can build and test the whole integration on any plan: connect the feed, embed it on your site, see it work. Until the account is on Pro, the map carries a small notice asking to upgrade — it never stops working, and visitors still get a usable map.


The feed contract

Response

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "id": "42",
      "geometry": { "type": "Point", "coordinates": [4.895, 52.370] },
      "properties": { "title": "Rijksmuseum", "category": "museum" }
    }
  ],
  "totalCount": 1234
}

Three rules that are easy to get wrong:

  1. Every feature needs a top-level id. It is the identity Mapsemble uses to hydrate a single feature when someone opens a popup. Use the CMS entity id (node/42, post ID 42).
  2. Coordinates are [longitude, latitude] — the opposite order from most CMS geo fields.
  3. totalCount is the full number of matching features, ignoring offset and limit. In WordPress that is $query->found_posts; in Drupal, the count query before the range is applied. Paging and result counts read from it.

Query parameters you receive

Parameter Meaning
mapId Which Mapsemble map is asking
extent Current viewport as a WKT POLYGON in EPSG:4326
offset, limit Paging window
orderBy Sort key, passed through from the map's order-by config
language Active widget language
filters JSON object of {"filter-slug": value}
remaining 1 means markers only — skip per-feature render work

When limit is absent, return everything. Mapsemble calls the feed without a limit to hydrate one feature by id; a feed that quietly caps the response makes popups fail with a 404. If your dataset is large, honour limit when it is present and stream the rest when it is not.

Any filter you configure with a passthrough key arrives as its own top-level parameter instead of inside filters. These names are reserved and cannot be used as filter slugs: mapId, extent, offset, limit, orderBy, language, filters, remaining.

Failure behaviour

A feed that errors, times out or returns malformed JSON renders an empty map — the failure is logged on our side, not shown to your visitor. Treat the endpoint as part of your page-render budget: it is called on every map interaction.


Filter options from your CMS

A filter can source its choices from your site instead of from the data. Set an options endpoint on the filter and return a JSON object:

{ "museum": "Museums", "gallery": "Galleries" }

Your endpoint receives mapsemble[{mapId}][filter]={slug}, plus mapsemble[{mapId}][search]= for autocomplete filters. Labels can also be objects with label and weight when you need to control ordering.


CMS-rendered popups

A remote feed can supply its own popup markup, so popups match your theme exactly. Put it in properties.__popup, as either an object:

{ "__popup": { "html": "<div class='card'>…</div>", "css": ".card{…}", "width": 320 } }

…rendered inside a shadow root, or a URL string, loaded in an iframe. Use __popup_mobile for a narrow-screen variant.

Cards are different. Mapsemble always builds the card itself for remote maps, so properties.__card is overwritten. To theme cards, either design them in the card editor or render them client-side with featureRenderer, which takes over both cards and popups.


Caching

Responses are not cached by default: every render calls your feed (requests within a single render are collapsed into one). Turn on response caching in the data source settings to reuse responses for a TTL you choose.

When caching is on, pass cacheVersion to the embed — a content hash, or post_modified in WordPress, or a cache tag in Drupal — and Mapsemble fetches fresh data the moment that value changes rather than waiting for the TTL:

Mapsemble.init({ container: '#map', mapId: '…', cacheVersion: '2026-08-19T10:41:00Z' });

cacheVersion is never forwarded to your endpoint; it only participates in our cache key.


The alternative: push instead of serve

If you would rather not expose an endpoint — or your content changes rarely — push it into Mapsemble instead with the features API: PUT up to 1000 features per request with remoteField set to your CMS entity id, and Mapsemble handles filtering, search and geocoding on its own copy. Available from the Starter plan.

Use a slug of lowercase letters, digits and underscores for remoteField (remote_id, not remote-id) — anything else is rejected and matching by remote id is skipped for that request.