---
title: "Vector tiles with polygon from GeoJSON in OpenLayers | Openlayers"
description: "Display GeoJSON polygons over vector tiles using OpenLayers."
---

> For AI agents: a documentation index is available at [/llms.txt](https://docs.maptiler.com/llms.txt). Markdown versions of all pages are available by appending .md to any URL.

# Vector tiles with polygon from GeoJSON in OpenLayers

This tutorial shows how to add a polygon feature from external GeoJSON to your vector tiles map. If you don’t know how to display vector tiles map follow this tutorial [Vector tiles in OpenLayers](../vector-tiles-in-openlayers/).

## Add GeoJSON layer to vector map

Insert the following GeoJSON vector layer definition snippet below the line of `olms.apply(map, styleJson)`; and don’t forget to set z-index because otherwise your geojson layer might be hidden below some layers of basemap.

```js
const geojsonLayers = new ol.layer.Vector({
  source: new ol.source.Vector({
    url: `https://api.maptiler.com/data/YOUR_DATA_ID/features.json?key=${key}`,
    format: new ol.format.GeoJSON(),
  }),
  style: new ol.style.Style({
    stroke: new ol.style.Stroke({
      color: 'grey',
      width: 1 // not connected with scale in screen resolution
    }),
    fill: new ol.style.Fill({
      color: 'rgba(165,80,51,0.8)',
    }),
  })
});
geojsonLayers.setZIndex(1); //don't forget to set this!

map.addLayer(geojsonLayers);
```

### Complete source code

```html
<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v10.1.0/ol.css">
  <script src="https://cdn.jsdelivr.net/npm/ol@v10.1.0/dist/ol.js"></script>
  <script src="https://unpkg.com/ol-mapbox-style@12.1.1/dist/olms.js"></script>
  <style>
    #map {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
    }
  </style>
</head>

<body>
  <div id="map">
    <a href="https://www.maptiler.com" style="position:absolute;left:10px;bottom:10px;z-index:999;"><img
        src="https://api.maptiler.com/resources/logo.svg" alt="MapTiler logo"></a>
  </div>
  <p><a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> <a
      href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a></p>
  <script>
    const key = 'YOUR_MAPTILER_API_KEY_HERE';
    const styleJson = `https://api.maptiler.com/maps/streets-v4/style.json?key=${key}`;

    const attribution = new ol.control.Attribution({
      collapsible: false,
    });

    const map = new ol.Map({
      target: 'map',
      controls: ol.control.defaults.defaults({ attribution: false }).extend([attribution]),
      view: new ol.View({
        constrainResolution: true,
        center: ol.proj.fromLonLat([0, 0]),
        zoom: 2
      })
    });
    olms.apply(map, styleJson);

    const geojsonLayers = new ol.layer.Vector({
      source: new ol.source.Vector({
        url: `https://api.maptiler.com/data/YOUR_DATA_ID/features.json?key=${key}`,
        format: new ol.format.GeoJSON(),
      }),
      style: new ol.style.Style({
        stroke: new ol.style.Stroke({
          color: 'grey',
          width: 1 // not connected with scale in screen resolution
        }),
        fill: new ol.style.Fill({
          color: 'rgba(165,80,51,0.8)',
        }),
      })
    });
    geojsonLayers.setZIndex(1);
    map.addLayer(geojsonLayers);
  </script>
</body>

</html>
```

1.  Import the new modules needed to add the new functionality.
    
    ```js
    import Map from 'ol/Map.js';
     import View from 'ol/View.js';
     import VectorLayer from 'ol/layer/Vector.js';
     import VectorSource from 'ol/source/Vector.js';
     import Style from 'ol/style/Style.js';
     import Fill from 'ol/style/Fill.js';
     import Stroke from 'ol/style/Stroke.js';
     import Attribution from 'ol/control/Attribution.js';
     import GeoJSON from 'ol/format/GeoJSON.js';
     import { defaults as defaultControls } from 'ol/control/defaults.js';
     import { fromLonLat } from 'ol/proj.js';
     import 'ol/ol.css';
     import { apply } from 'ol-mapbox-style';
    ```
    
2.  Insert the following GeoJSON vector layer definition snippet below the line of `apply(map, styleJson)`; and don’t forget to set z-index because otherwise your geojson layer might be hidden below some layers of basemap.
    
    ```js
    const geojsonLayers = new VectorLayer({
       source: new VectorSource({
         url: `https://api.maptiler.com/data/YOUR_DATA_ID/features.json?key=${key}`,
         format: new GeoJSON(),
       }),
       style: new Style({
         stroke: new Stroke({
           color: 'grey',
           width: 1 // not connected with scale in screen resolution
         }),
         fill: new Fill({
           color: 'rgba(165,80,51,0.8)',
         }),
       })
     });
     geojsonLayers.setZIndex(1);
     map.addLayer(geojsonLayers);
    ```
    

### Complete source code

```bash
npm install --save ol ol-mapbox-style
```

#### main.js

```js
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import VectorLayer from 'ol/layer/Vector.js';
import VectorSource from 'ol/source/Vector.js';
import Style from 'ol/style/Style.js';
import Fill from 'ol/style/Fill.js';
import Stroke from 'ol/style/Stroke.js';
import Attribution from 'ol/control/Attribution.js';
import GeoJSON from 'ol/format/GeoJSON.js';
import { defaults as defaultControls } from 'ol/control/defaults.js';
import { fromLonLat } from 'ol/proj.js';
import 'ol/ol.css';
import { apply } from 'ol-mapbox-style';

const key = 'YOUR_MAPTILER_API_KEY_HERE';
const styleJson = `https://api.maptiler.com/maps/streets-v4/style.json?key=${key}`;

const attribution = new Attribution({
  collapsible: false,
});

const map = new Map({
  target: 'map',
  controls: defaultControls({attribution: false}).extend([attribution]),
  view: new View({
    constrainResolution: true,
    center: fromLonLat([0, 0]),
    zoom: 2
  })
});
apply(map, styleJson);

const geojsonLayers = new VectorLayer({
  source: new VectorSource({
    url: `https://api.maptiler.com/data/YOUR_DATA_ID/features.json?key=${key}`,
    format: new GeoJSON(),
  }),
  style: new Style({
    stroke: new Stroke({
      color: 'grey',
      width: 1 // not connected with scale in screen resolution
    }),
    fill: new Fill({
      color: 'rgba(165,80,51,0.8)',
    }),
  })
});
geojsonLayers.setZIndex(1);
map.addLayer(geojsonLayers);
```

#### index.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="robots" content="noindex">
  <title>Vector tiles with polygon from GeoJSON in OpenLayers | NPM example</title>
  <link rel="stylesheet" href="./style.css">
</head>
<body>
  <div id="map">
    <a href="https://www.maptiler.com" style="position:absolute;left:10px;bottom:10px;z-index:999;"><img src="https://api.maptiler.com/resources/logo.svg" alt="MapTiler logo"></a>
  </div><p><a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a></p>
  <script type="module" src="./main.js"></script>
</body>
</html>
```

#### style.css

```css
#map {position: absolute; top: 0; right: 0; bottom: 0; left: 0;}
```

### Summary

To properly add GeoJSON to OpenLayers map you need to create a new vector layer and give z-index to this layer.

## Related examples

### [Polygon GeoJSON Layer](https://docs.maptiler.com/openlayers/examples/geojson-polygon/)

Tutorials

Display Polygon GeoJSON data on map using OpenLayers.

### [Vector tiles](https://docs.maptiler.com/openlayers/examples/vector-tiles-in-openlayers/)

Tutorials

Display vector tiles in OpenLayers with ol-mapbox-style plugin.
