The Real-World Challenge: One Map, Multiple Destinations
A WordPress Backend Serving Maps to a Non-WordPress CMS
The university project had an embedding requirement that most map tutorials do not cover: the map needed to appear on a website that was not running WordPress. The target site used Bloomreach CMS — a Java-based enterprise content management system with its own asset pipeline and strict requirements for third-party content.
This ruled out any approach that relied on WordPress-specific rendering. The solution needed to be self-contained: a map that could be embedded in a non-WordPress environment without requiring that environment to understand or execute any WordPress code.
What Bloomreach and Similar CMS Platforms Require from Third-Party Widgets
The Bloomreach CMS had a formal widget specification. Widgets had to be delivered as a zip file containing an index.html at the root. Only the markup between <!-- WIDGET --> and <!-- /WIDGET --> comment tags would be included. JavaScript files had to be marked with data-widget="js" and CSS files with data-widget="css". All paths had to be relative — root-relative paths would not be converted by the CMS’s asset pipeline.
Building a Scalable Shortcode
Shortcode Architecture for Multiple Maps on One Page
The shortcode accepts a map ID and an optional height parameter. Multiple shortcodes can appear on the same page — each renders its own map container with a unique ID, and each map is initialized independently using its own data object to prevent conflicts between instances.
Passing PHP Data to JavaScript with wp_localize_script
Global configuration data — such as the plugin URL needed to reference asset files — is passed from PHP to JavaScript using wp_localize_script. Never hardcode URLs in JavaScript files — they break when the plugin is moved to a different domain or subdirectory.
Supporting Custom Height via Shortcode Attribute
The height attribute allows content editors to control the map’s vertical dimension without touching CSS. Accept any valid CSS height value and apply it directly to the map container’s inline style. Use esc_attr to prevent XSS.
Creating a Standalone iFrame Embed Page
Handling the Embed Query Parameter
The standalone embed page is triggered by a query parameter. A template_redirect action hook intercepts requests containing this parameter, fetches the map data, and outputs a complete HTML page before WordPress’s normal template rendering runs. The page exits after output, preventing WordPress’s standard HTML wrapper from being appended.
Outputting a Self-Contained HTML Page with All Assets
The standalone embed page must include everything it needs in a single response: Leaflet CSS and JS, plugin CSS and JS, the map data, and the map container HTML. Set the body and HTML to 100% height and width with overflow hidden to make the map fill its iframe container completely.
Generating and Copying the Embed Code from the Admin
Display the iframe embed code automatically once a map is published. Include a height input that updates the embed code in real time so editors can adjust iframe dimensions without editing the code manually. Provide a copy button for one-click copying.
Meeting Third-Party Widget Specifications
Using WIDGET Comment Tags Correctly
Wrap only the map container and its required script tag within the <!-- WIDGET --> and <!-- /WIDGET --> comments. Keep test scaffolding — page structure, styles for testing in isolation — outside the tags so they do not appear in production.
Marking Assets with data-widget Attributes
Script and link tags that the CMS should include must be marked with data attributes. Use data-widget="js" on script tags and data-widget="css" on link tags. Unmarked tags are stripped by the CMS’s import process — this includes Leaflet’s CDN script tag, not just your plugin’s assets.
Keeping All Paths Relative, Not Root-Relative
All asset references must use paths relative to the widget’s own location — for example, ./css/map.css rather than /wp-content/plugins/my-map/public/css/map.css. This is the most common cause of broken widgets after CMS import, and it is entirely preventable with discipline during development.
Common Pitfalls with Map Embedding
Absolute Paths Breaking Inside Third-Party CMS
Even a single absolute path in a widget will cause that asset to fail when deployed to a CMS that cannot resolve the original domain. Audit every asset reference before delivering — image src attributes, CSS url() values, and JavaScript URL strings all need to be relative.
iFrame Height Not Adapting to Container
iFrames do not automatically resize to match their content height. Set an explicit pixel height on the iframe element, or use JavaScript’s postMessage API to communicate the desired height from inside the iframe to the parent page.
Summary and What Comes Next
A well-designed embed system makes a WordPress map plugin genuinely useful beyond WordPress. Build a shortcode for in-WordPress embedding, a standalone iframe page for external sites, and follow third-party widget specifications carefully when delivering to enterprise CMS platforms. Keep all asset paths relative and generate embed codes automatically in the admin.
With embedding solved, the final piece is performance. The next article covers conditional asset loading, conflict resolution, and lazy loading strategies to ensure your map does not negatively impact Core Web Vitals scores.
This article is part of our complete guide:
How to Build an Interactive Map in WordPress: A Complete Guide for Developers
Read the full guide →