diff --git a/src/radical/orbit/data/orbit_explorer.html b/src/radical/orbit/data/orbit_explorer.html
index 580423c..72b5e5b 100644
--- a/src/radical/orbit/data/orbit_explorer.html
+++ b/src/radical/orbit/data/orbit_explorer.html
@@ -2045,6 +2045,9 @@
${escHtml(ui.title)} — ${endpointName}
// Open SSE event stream for push notifications
setupEventSource();
+
+ // a #plugin// deep link can now be honoured
+ applyDeepLink();
} catch (e) {
setConnectionStatus('disconnected');
@@ -2603,7 +2606,25 @@ ${escHtml(ui.title)} — ${endpointName}
if (entry && page && entry.module.onShow) {
entry.module.onShow(page, entry.api);
}
+
+ // the page is addressable: keep the URL in step (replaceState does
+ // not retrigger the hashchange listener)
+ history.replaceState(null, '',
+ `#plugin/${encodeURIComponent(endpointName)}`
+ + `/${encodeURIComponent(pluginName)}`);
+ }
+
+ // ── URL deep links ───────────────────────────────────────────
+ // #plugin// opens that plugin's page once the
+ // Explorer is connected; external pages (the DT dashboard's pool
+ // titles, say) can link straight to a plugin this way.
+ function applyDeepLink() {
+ const m = location.hash.match(/^#plugin\/([^/]+)\/([^/]+)$/);
+ if (m && isConnected) {
+ showPluginPage(decodeURIComponent(m[1]), decodeURIComponent(m[2]));
+ }
}
+ window.addEventListener('hashchange', applyDeepLink);
// ─────────────────────────────────────────────────────────────
// SSE Notification handler