Skip to main content

Storage Providers

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

leaflet.html
let url = "https://my-storage-provider.like-aws-s3.com/FILENAME.pmtiles"
layer = new 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#

  1. From your S3 Bucket's "Permissions" tab, scroll to the Cross-origin resource sharing (CORS) editor.
  2. Add this JSON policy, replacing "https://example.com" with your domains or "*" for all domains. See The S3 CORS documentation.
s3_cors.json
[
{
"AllowedHeaders": ["Range"],
"AllowedMethods": ["GET","HEAD"],
"AllowedOrigins": ["https://example.com"]
}
]
  1. Ensure that your PMTiles has public read access:

Google Cloud#

google_cloud_cors.json
[
{
"origin": ["https://example.com"],
"method": ["GET","HEAD"],
"responseHeader": ["range"],
"maxAgeSeconds": 300
}
]

Microsoft Azure#

  • HEAD requests for ranges return 200 instead of 206
  • Configuration through Web Portal

DigitalOcean Spaces#

Backblaze B2#

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

HTTP Servers#

Nginx#

Caddy#