MapSnippets logoMapSnippets logo

Add Markers and Popups in OpenLayers

OpenLayers

Place point features on a vector layer and display popups with ol.Overlay on click in OpenLayers.

progress_activityLoading map...
var parisFeature = new ol.Feature({
  geometry: new ol.geom.Point(ol.proj.fromLonLat([2.3522, 48.8566])),
  name: 'Paris'
});
var eiffelFeature = new ol.Feature({
  geometry: new ol.geom.Point(ol.proj.fromLonLat([2.2945, 48.8584])),
  name: 'Eiffel Tower'
});
var vectorLayer = new ol.layer.Vector({
  source: new ol.source.Vector({ features: [parisFeature, eiffelFeature] }),
  style: new ol.style.Style({
    image: new ol.style.Circle({ radius: 8, fill: new ol.style.Fill({ color: '#e63946' }), stroke: new ol.style.Stroke({ color: '#fff', width: 2 }) })
  })
});
var map = new ol.Map({
  target: 'map',
  layers: [
    new ol.layer.Tile({ source: new ol.source.XYZ({ url: 'https://api.maptiler.com/maps/streets-v4/256/{z}/{x}/{y}.png?key=YOUR_MAPTILER_KEY', attributions: '&copy; <a href="https://www.maptiler.com/copyright/">MapTiler</a>' }) }),
    vectorLayer
  ],
  view: new ol.View({ center: ol.proj.fromLonLat([2.33, 48.86]), zoom: 13 })
});
var popupEl = document.getElementById('popup');
var overlay = new ol.Overlay({ element: popupEl, positioning: 'bottom-center', offset: [0, -12] });
map.addOverlay(overlay);
map.on('click', function(evt) {
  var feature = map.forEachFeatureAtPixel(evt.pixel, function(f) { return f; });
  if (feature) {
    popupEl.style.display = 'block';
    popupEl.innerHTML = '<strong>' + feature.get('name') + '</strong>';
    overlay.setPosition(evt.coordinate);
  } else {
    popupEl.style.display = 'none';
  }
});

How it works

OpenLayers uses vector layers with features for markers instead of dedicated marker objects. Each ol.Feature has a geometry (here ol.geom.Point) and optional properties like name.

A styled ol.layer.Vector renders the points as colored circles. For popups, ol.Overlay anchors a regular HTML element to a map coordinate. The click handler uses forEachFeatureAtPixel to detect which feature was clicked.

Key APIs

API Description Docs
ol.Feature A geographic feature with geometry and properties openlayers.org
ol.geom.Point Point geometry openlayers.org
ol.Overlay Position an HTML element on the map openlayers.org
map.forEachFeatureAtPixel() Hit-detect features at a pixel openlayers.org

FAQ

How do I use custom icon images instead of circles?

Replace ol.style.Circle with ol.style.Icon in the style configuration, providing a src URL to your icon image.

Can I make the popup close when clicking elsewhere?

Yes. The else branch in the click handler hides the popup when no feature is detected at the click location.

Common mistakes

  • Forgetting ol.proj.fromLonLat() when creating Point geometries: coordinates must be in EPSG:3857
  • Not adding the overlay to the map with map.addOverlay()
  • Using evt.coordinate without checking if a feature was actually hit
auto_awesome

Build maps using OpenLayers with AI

Generate code like this add markers and popups in openlayers example using the OpenLayers skill in your IDE.