Skip to main content

Storage Providers

To use a PMTiles archive hosted on the internet, change the URL in your JavaScript code:

leaflet.html
let url = "https://my-storage-provider.like-aws-s3.com/FILENAME.pmtiles"layer = protomaps.leafletLayer({url:url,bounds:bounds})layer.addTo(map)

PMTiles archives require HTTP byte serving as well as CORS. It's been tested with:

note

Storage services usually bill by number of GET requests and the total number of bytes stored. It's important to understand these costs when hosting PMTiles, as each Range tile request will count as a GET.

Amazon S3#

  • From your S3 Bucket's "Permissions" tab, scroll to the Cross-origin resource sharing (CORS) editor.
  • Add this JSON policy, replacing "https://example.com" with your domains or "*" for all domains. See The S3 CORS documentation.
  • only HTTP/1.1 supported
s3_permissions.json
{    "Version": "2012-10-17",    "Id": "",    "Statement": [        {            "Sid": "PublicRead",            "Effect": "Allow",            "Principal": "*",            "Action": "s3:GetObject",            "Resource": "arn:aws:s3:::example-bucket/*"        }    ]}
s3_cors.json
[    {        "AllowedHeaders": ["Range"],        "AllowedMethods": ["GET","HEAD"],        "AllowedOrigins": ["https://example.com"],        "ExposeHeaders": ["ETag"]    }]
  1. Ensure that your PMTiles has public read access:

Google Cloud#

google_cloud_cors.json
[    {      "origin": ["https://example.com"],      "method": ["GET","HEAD"],      "responseHeader": ["range","etag"],      "maxAgeSeconds": 300    }]
gsutil cors set google_cloud_cors.json gs://my-bucket-name

Microsoft Azure#

  • only HTTP/1.1 supported

  • Configuration through Web Portal

  • CORS Configuration - in left sidebar Resource Sharing (CORS)

    • Set Allowed Headers to Range
    • Set Exposed Headers to range,accept-ranges,etag

DigitalOcean Spaces#

  • only HTTP/1.1 supported (even with CDN enabled)
  • CORS configuration in Web UI on bucket settings
  • use S3Cmd config to expose ETag header

Backblaze B2#

backblaze_cors.json
[    {      "corsRuleName": "allowHeaders",      "allowedOrigins": ["https://example.com"],      "allowedOperations":["b2_download_file_by_name"],      "allowedHeaders": ["range"],      "maxAgeSeconds": 300    }]

Scaleway#

  • only HTTP/1.1 supported

HTTP Servers#

Nginx#

Caddy#