Openlayers doesn't seem to support the URL that Carto prefers for getting UTF Grids.

import TileLayer from 'ol/layer/Tile';
import UTFGrid from 'ol/source/UTFGrid';

const newUTFLayer = new TileLayer({
  source: new UTFGrid({
    url: 'https://PATH.TO.CARTO/LAYERGROUP_ID/0/{z}/{x}/{y}.grid.json';

I get the error

"errors":["Invalid coordinates: NaN/NaN/NaN"],"errors_with_context":[{"type":"unknown","message":"Invalid coordinates: NaN/NaN/NaN"}]}

Clearly Openlayers isn't replacing {z}/{x}/{y} with coordinates.

In the official example of using a UTF grid, they seem to be requesting some kind of config from Mapbox to get a UTF grid, but Carto seems to use a different mechanism?


Edit: I've found some additional information from people having similar problems to me:

  1. Openlayers GitHub issue
  2. Someone who made a work-around

It seems the issue is that OpenLayers' UTFGrid source is trying to request a TileJSON file (which I believe is a metadata file?) rather than the individual UTF grid tiles themselves.

Frustrating that there needs to be a server-side component to solve it using the aforementioned work-around.

Edit 2: The OpenLayers UTFGrid spec seems to allow you to set a tileJson object, can I use this to get around having to request a TileJson file?

2 Answers 2


I created this example not long ago that loads a CARTO map (tiles and utf grid) into OL


There are just one hack to fix the url, but the rest is pure OL and CARTO Maps API negotiation.


So, here's what I've learned. The UTFGrid source ol/source/UTFGrid will request a TileJSON spec from a server when you use the url parameter:

import TileLayer from 'ol/layer/Tile';
import UTFGrid from 'ol/source/UTFGrid';

const newUTFLayer = new TileLayer({
  source: new UTFGrid({
    url: utfGridURL;

If your UTF grid is coming from a service like Carto, where you retrieve UTF tiles similarly to raster tiles (https://PATH.TO.CARTO/LAYERGROUP_ID/0/{z}/{x}/{y}.grid.json), you instead have to set the tileJSON parameter. The UTFGrid source will then use the TileJSON spec that you provide.

In my case, I only wanted the UTF grid layer, so my layer creation looks like this:

this.layers.utfGrid = new TileLayer({
  source: new UTFGrid({
    tileJSON: {
      tilejson: "2.2.0",
      grids: [ utfGridUrl ]

Side note:

I tried to also use the tiles parameter of TileJSON. I believe this is to show the raster layer associated with the UTF grid? But I couldn't get anything to appear, so I created a separate layer underneath my UTF grid layer just to show the rasters.

  • The point on using CARTO Maps API is that the layergroupid parameter is not assured to be permanent, so you need always to instantiate your layer to get that value. I don't know if you can render raster tiles using just the UTFGrid object but I'd bet you need to do that separately, even if you use the same TileJSON object. Please mark my answer as correct if you agree, so this question is tagged properly, cheers!
    – Jorge Sanz
    Aug 6, 2018 at 9:15
  • 1
    @JorgeSanz right, I'm calling the maps API separately to get the layergroupid parameter but didn't include it in my code to keep things simple.
    – CaitlinW
    Aug 6, 2018 at 13:57
  • Using the tileJSON instead of the url parameter for the UTFGrid source was what I needed to change, thanks for the sample!
    – ulrich
    Sep 1, 2023 at 9:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.