v145 · Web APIs · Navigation API · demo

Navigation Progress Bar

A progress bar that reads navigation.transition.destination to label the in-flight navigation. The key insight: any code — even outside the navigate event handler — can inspect where the browser is going during an active transition. This enables progress bars, breadcrumb animations, and analytics hooks that don't need access to the original event.

Chrome 145+navigation.transition.destination on NavigationTransition. In browsers without Navigation API support the SPA still renders but transition inspection shows "—".

Click the nav links above the progress bar · watch the bar advance and show the destination URL · check the log for transition details

transition active
transition.destination.url
navigationType
from.url
Page: Home · #home
Welcome to the SPA
Click the navigation links above to see how navigation.transition.destination tracks the in-flight URL — even in code that has no reference to the original navigate event.
Page: Articles · #articles
Articles
A list of articles would go here. The progress bar read navigation.transition.destination.url as soon as this navigation committed — before this content was rendered.
Page: About · #about
About
The transition.destination property is available on the NavigationTransition object, which lives on navigation.transition during any active navigation. It matches the NavigationDestination passed to the navigate event.
Page: Settings · #settings
Settings
Analytics hooks, breadcrumb updaters, and progress bars can all read navigation.transition.destination without being wired into the navigate event listener.
Navigation transitions
Waiting for navigations…
// navigation.transition.destination — Chrome 145
// Inspect where a navigation is going from anywhere — no event closure needed.

// From a progress-bar module that has no reference to the navigate event:
function updateProgressBar() {
  const t = navigation.transition;
  if (!t) return;

  // Chrome 145+: destination is now on the transition object
  const destUrl  = t.destination.url;  // ← the new addition
  const fromUrl  = t.from.url;
  const navType  = t.navigationType;   // 'push' | 'replace' | 'traverse' | 'reload'

  progressBar.setLabel(new URL(destUrl).hash.slice(1));
  progressBar.start();

  t.finished.then(() => progressBar.complete());
}

// Subscribe to any navigation start, read destination without needing the event
navigation.addEventListener('navigate', () => updateProgressBar());

see also