☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

Unable to load WMTSTileSource url, in CustomJS, CORS policy: No 'Access-Control-Allow-Origin'

Community Support
Eric_Johnson
Eric_Johnson

Hi, setting the WMTSTileSource url works fine in python, but bokeh cant load it inside a CustomJS.

Getting the error “Access to image at ‘https://tile.openstreetmap.org/{z}/{x}/{y}.png’ from origin ‘https://xxxx.xxxxxxx.ca’ has been blocked by Access to image at ‘https://tile.openstreetmap.org/{z}/{x}/{y}.png’ from origin ‘https://xxxx.xxxxxxx.ca’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.”

I changed my personal address above to xxxx.xxx…

Does bokeh have a way around this? like sending the Get to a proxy or something? I bet changing the Vendors (bokeh.tile_providers — Bokeh 2.4.2 Documentation) in a CustomJS could get around this, but Vendorsdoesnt appear to exist in my WMTSTileSource…

Minimal example here:

from bokeh.models import WMTSTileSource, Button, CustomJS
from bokeh.plotting import figure, show, output_notebook
from bokeh.tile_providers import *
from bokeh.layouts import row

TEST_tilesource = WMTSTileSource(url='https://tile.opentopomap.org/{z}/{x}/{y}.png',
                     snap_to_zoom=True)

output_notebook()
tile_provider = get_provider(TEST_tilesource)

p = figure(x_range=(-14000000, -6000000),
           y_range=(6000000, 7000000),
           #x_axis_type="mercator",
           #y_axis_type="mercator",
           width=500,
           height=500)

p.add_tile(tile_provider)


SwitchBasemap = Button(label="Switch Basemap", align='center')
SwitchBasemap.js_on_click(CustomJS(args=dict(wmts=p.renderers[0].tile_source), code="""
        console.log(wmts.url);
        wmts.url = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
        
        wmts.change.emit();
        console.log(wmts.url);
    """))
        

show(row(p,SwitchBasemap))
⌁   Link to post
Bryan
Bryan

I don’t think anyone has ever asked about swapping out the tile provider before. I’d like to think there is a simple solution, but browsers also have security concerns/polices around loading external resources into HTML canvases, so it will require some investigation. A GitHub Issue with details woudl be appropriate.

In the mean time, my only suggestion is to try making entire separate plots in layout, and having the callback toggle the visibility of each, instead of setting the tile provider url.

⌁   Link to post

End of archived discussion · Replies are disabled