Map Extender
Docs Gallery

Guide

Creating a plugin

This walks through writing a plugin by hand in the built-in editor, from a blank plugin to one running on a real page. If you'd rather describe what you want and have an AI write the code, see Writing a plugin with AI instead β€” everything below still applies to reviewing and testing what it gives you.

Step by step

  1. Open the plugins page

    Click the Map Extender icon in your browser toolbar, then Open Plugins. This opens the extension's options page, where every plugin β€” built-in and your own β€” is listed.

  2. Click New Plugin

    Starts a blank plugin with a working template already in the code editor, so you have something that runs before you change anything.

  3. Fill in name, description, and usage

    The usage field is a short line shown in the popup when the plugin is enabled β€” "Click Measure, then click the map" is the kind of thing that goes there. It's optional, but it's the only hint a user gets about how to actually use the plugin.

  4. Set match patterns

    These decide which sites the plugin runs on β€” *://*/* for everywhere, or something narrower like https://example.com/maps/*. See the API reference for the exact syntax.

  5. Add a settings schema, if the plugin needs one

    Skip this for a plugin with no configurable options. Otherwise see Settings schema β€” it's a JSON array, editable either as JSON directly or through the form UI.

  6. Write the code

    Plain JavaScript against the plugin object β€” the full surface is in the API reference. The minimal example below is a reasonable starting point.

  7. Save, enable, and test

    Saving doesn't turn a plugin on by itself β€” enabling is a separate, per-site switch in the popup. Open a page with a map that matches your patterns, enable the plugin there, and check the log panel on the plugins page if something doesn't work.

Minimal example

plugin.mapHook.onHook(function () {
  var layer = plugin.mapHook.createMarkerLayer();

  layer.addMarker({
    id: 'example',
    lat: 45.0703,
    lng: 7.6869,
    color: 'red',
    popup: 'Hello from Map Extender'
  });

  plugin.log('Marker added');
});

Things that are easy to get wrong

  • Clean up after yourself. Layers and map subscriptions are disposed of automatically. Anything else β€” an injected <style>, a timer, a listener on your own control markup β€” needs plugin.onDispose, or it survives until the page reloads.
  • plugin.fetch, not fetch. A direct fetch call from a plugin is subject to the host page's own rules; plugin.fetch goes through the extension instead.
  • Debounce anything driven by map movement, and ignore stale responses once a newer one has started. Panning fires often, and public data APIs are usually donated infrastructure that shouldn't be hammered.
  • Tile URLs only substitute {z}, {x}, and {y}. An {s} subdomain placeholder is left literal on Google Maps and every tile 404s β€” use one fixed hostname.
  • Guard your control lookup. document.querySelector('[data-map-control-id="…"]') can return null if the map container went away β€” log and stop rather than letting it throw.

Debugging

Every plugin.log, plugin.warn, and plugin.error call appears in the log panel on the plugins page, scoped to that one plugin β€” that's the first place to look when something silently doesn't work. Errors also show up in the browser's own DevTools console (right-click the page β†’ Inspect β†’ Console).

Nothing happening at all?

Check that the plugin is actually enabled for the site you're on β€” saving a plugin never enables it, that's a separate per-site toggle in the popup β€” and that your match patterns actually cover the page's URL.