jupyterlab_server_proxy_launcher_fix
v1.0.4
Published
Fix to the issue that when launchers configured in the jupyter config file with svg icons are in a different category than notebooks, icons are not displayed
Maintainers
Readme
jupyterlab_server_proxy_launcher_fix
JupyterLab extension that fixes SVG icon display for jupyter-server-proxy launchers when placed in custom categories other than "Notebook" or "Console".
[!WARNING] This extension is a temporary fix for jupyterhub/jupyter-server-proxy. Once the upstream project implements proper icon support for custom launcher categories, this extension will be deprecated. We look forward to our own obsolescence.
The Problem
When configuring jupyter-server-proxy launchers with custom categories (e.g., "Services", "Tools"), SVG icons fail to display. This happens because JupyterLab's launcher widget handles icons differently based on category:
- Notebook/Console categories: Uses
kernelIconUrlproperty - works correctly - Other categories: Calls
commands.icon(command, args)to get the icon - server-proxy'sserver-proxy:opencommand doesn't define aniconproperty, so icons are missing
The Fix
This extension wraps JupyterLab's commands.icon() method to intercept calls for the server-proxy:open command and return pre-cached LabIcon instances.
How it works:
- Fetches server-proxy configuration from
/server-proxy/servers-infoendpoint - Pre-fetches SVG icons and creates LabIcon instances for non-kernel categories
- Wraps
app.commands.icon()to return cached icons when command isserver-proxy:open - Matches icons by
args.title(handles both plain titles and titles with[↗]suffix fornew_browser_tab: true)
Implementation details:
- No command override: Preserves server-proxy's original
executefunction completely - No timing issues: Wrapper intercepts all calls regardless of extension load order
- No private API access: Uses public method wrapping instead of accessing internal
_commandsMap - Non-destructive: Original behavior preserved for all other commands
Fix Implementation Details
The extension consists of frontend TypeScript code that wraps the commands registry icon method.
Frontend Implementation (src/index.ts):
- Icon Caching: Fetches server info, creates LabIcon from
icon_urlfor each non-kernel category launcher, caches by title - Title Matching: Caches icons under both plain title and
${title} [↗]suffix (server-proxy appends this whennew_browser_tab: true) - Method Wrapping:
const originalIcon = app.commands.icon.bind(app.commands)preserves original, then(app.commands as any).icon = ...installs wrapper - Conditional Return: If
id === 'server-proxy:open'andargs.titlematches cache key, returns cached LabIcon; otherwise delegates to original
Icon Utilities (src/iconUtils.ts):
- SVG Fetching:
fetchSvgIcon(url, name)fetches SVG content and creates LabIcon instance - Fallback Icons:
createTextIcon(name, title)generates simple SVG with first letter when icon_url unavailable
Requirements
- JupyterLab >= 4.0.0
- jupyter-server-proxy installed and configured
Install
To install the extension, execute:
pip install jupyterlab_server_proxy_launcher_fixUninstall
To remove the extension, execute:
pip uninstall jupyterlab_server_proxy_launcher_fix