Build multi-page apps with client-side routing

Navigate between views, share URLs, and read URL parameters in deephaven.ui

June 1 2026

Joseph NumainvilleJoseph NumainvilleDeveloper @Deephaven
Risograph screen print illustration of a compass or signpost with multiple directional arrows pointing to floating dashboard cards, bold blue red and yellow color palette, overlapping geometric color blocks

You can now split a deephaven.ui application into multiple pages, each with its own bookmarkable URL. Navigate between views without a full page reload, share links that open directly to a filtered dashboard, and let users hit the back button to retrace their steps. Route parameters, query strings, and browser history all work out of the box.

Client-side routing in deephaven.ui lets you build multi-page applications with shareable URLs, route parameters, and browser-native navigation, all in Python.

This blog will walk through what's available and show how to build a simple multi-page app.

What is client-side routing?

If you've used frameworks like React Router or Next.js, the concept is familiar: you define a set of URL patterns (routes), and the framework renders the right component based on the current URL. The browser's back and forward buttons work, users can bookmark specific pages, and you can share a URL that takes someone directly to a filtered view.

deephaven.ui now provides the same capability. The core pieces are:

  • ui.router and ui.route: Define a hierarchy of routes that map URL paths to components.
  • ui.link: Render a clickable link that navigates within your app (using the new to prop) or to an external URL (using the preexisting href prop).
  • ui.use_params(): Read route parameters (e.g., {symbol} from the path).
  • ui.use_query_param(name): Read a single query parameter from the URL.
  • ui.use_set_query_param(name): Get a setter function that updates a query parameter in the URL.

There are additional hooks for more advanced use cases: use_navigate for programmatic navigation from event handlers, use_path to read the current path, use_query_params to get all query parameters at once, and use_url_components for low-level URL access.

Let's build something with the core features.

Example: stock dashboard with route and query parameters

This app has two pages: a stock list with a filter, and a detail page for individual symbols. The filter is stored in the URL as a query parameter (?sym=DOG), and the detail page uses a route parameter (/stocks/FISH). Navigation uses ui.link.

That's it. With this code running:

  • / renders the stock list. Picking a symbol from the picker updates the URL to /?sym=DOG, filtering the table. Share that URL of a dashboard and the recipient sees the same filter applied.
  • /stocks/FISH renders the detail page. ui.use_params() extracts "FISH" from the {symbol} segment.
  • /anything-else renders the "not found" page thanks to the * wildcard.
  • ui.link handles all navigation without full page reloads, and the browser's back button works as expected.

Why use this?

Before routing, the only way to build multi-page deephaven.ui apps was to toggle visibility with state variables or use tab components. That works, but you can't share a URL that takes someone to a specific page and the browser's back button doesn't undo navigation.

With routing, the URL is the state. Bookmarks work, links are shareable, and each page is its own component.

Things to keep in mind

  • Always include a wildcard route (path="*") so unmatched paths render something useful rather than an error.
  • Route parameters are always strings. Validate them before using them in queries.
  • Deephaven reserves the path segment /-/ and query parameters starting with _ or dh. Don't use those in your app.

Get started

The router and all navigation hooks are available now in deephaven-plugin-ui. Install or upgrade:

For full API details, check out the docs for ui.router, ui.link, use_params, use_query_param, use_set_query_param, use_navigate, use_path, use_query_params, and use_url_components.