I have an interactive visualization that I’ve put together in a Jupyter notebook and am rendering with a viz.show() at the end of the notebook. Is there a way to specify a favicon for the resulting webpage that is created upon execution of the notebook? The examples I’ve seen so far this morning for specifying a favicon all seem to be in the context of a template.
1 Like
I found the below solution, but it briefly flashes the panel favicon before loading yours.
import panel as pn
pn.extension()
FAVICON_PATH = "assets/favicon.ico"
def enforce_favicon():
html = f"""
<script>
// Function to set your favicon and remove defaults
function setFavicon() {{
// Remove all existing favicon links
document.querySelectorAll('link[rel="icon"], link[rel="shortcut icon"]').forEach(e => e.remove());
// Create new link tag for your favicon
const link = document.createElement('link');
link.rel = 'icon';
link.href = '{FAVICON_PATH}';
document.head.appendChild(link);
}}
// Immediately attempt to set favicon (for preload)
setFavicon();
// Observe head for any favicon changes (Panel sometimes re-adds its own)
const observer = new MutationObserver((mutations) => {{
const hasPanelFavicon = Array.from(document.querySelectorAll('link[rel="icon"]'))
.some(l => l.href.includes('panel'));
if (hasPanelFavicon) {{
setFavicon();
}}
}});
observer.observe(document.head, {{ childList: true, subtree: true }});
// Also run once after full DOM load
window.addEventListener('load', setFavicon);
</script>
"""
return pn.pane.HTML(html, width=0, height=0, margin=0, sizing_mode="fixed")
# --- Example dashboard ---
dashboard = pn.Column(
enforce_favicon(),
pn.pane.Markdown("## 🦊 Your favicon is locked — no flash, no revert."),
pn.Spacer(height=400),
)
dashboard.servable()