chrome/browser/web_applications/docs/navigation_capturing.md
Navigation Capturing is a system in Chrome that allows web app links and programmatically triggered navigations to be captured and opened inside an installed Progressive Web App (PWA) window, instead of opening in a standard browser tab. It can also focus or navigate existing app windows based on the app's configuration.
The lifecycle of a captured navigation spans across the navigation framework and the web applications system:
sequenceDiagram
participant BN as browser_navigator.cc
participant NCP as NavigationCapturingProcess
participant NH as NavigationHandle
participant NCRT as NavigationCapturingRedirectionThrottle
BN->>NCP: MaybeHandleAppNavigation(params)
Note over NCP: Creates NavigationCapturingProcess if enabled
BN->>NCP: GetInitialNavigationParamsOverride(params)
NCP-->>BN: Returns NavigationCapturingOverride (or nullopt)
Note over BN: Applies overrides to NavigateParams
BN->>NH: Creates NavigationHandle
BN->>NCP: AttachToNavigationHandle(NH, process)
Note over NCP: Process is now owned by NavigationHandle
loop For each redirect
NH->>NCRT: Redirect observed
NCRT->>NCP: HandleRedirect()
Note over NCP: Evaluates redirect URL and target app
NCP-->>NCRT: Returns ThrottleCheckResult
end
Note over NCP: On destruction, records metrics
The process begins in Navigate() within
browser_navigator.cc.
If the navigation capturing experiment is enabled, it calls
NavigationCapturingProcess::MaybeHandleAppNavigation() to determine if this
navigation is a candidate for capturing. If so, it creates a
NavigationCapturingProcess instance.
GetInitialNavigationParamsOverride)browser_navigator.cc calls GetInitialNavigationParamsOverride() on the
process. This method evaluates the source of the navigation, the destination
URL, and the target app's launch handler configuration (e.g., client_mode). It
returns a NavigationCapturingOverride which can specify:
NavigateNew: Open a new app window.NavigateExisting: Navigate an existing tab in an app window.FocusExisting: Focus an existing tab/window and enqueue a launch event
(cancelling the current navigation).Cancel: Abort the navigation.nullopt: Do not capture, proceed with normal browser navigation.The overrides are applied to NavigateParams, modifying where the navigation
will land.
Once the target WebContents is determined (and possibly created), the
NavigationCapturingProcess is attached to the NavigationHandle using
NavigationCapturingProcess::AttachToNavigationHandle() or scheduled to attach
to the next navigation. The process is owned by the navigation handle for its
duration.
NavigationCapturingRedirectionThrottle)During the navigation, the
NavigationCapturingRedirectionThrottle
intercepts redirects. It calls HandleRedirect() on the attached
NavigationCapturingProcess. Because redirects can change the origin of the
navigation (moving in or out of the app's scope), the process must re-evaluate
whether the navigation should still be captured by the initial app, a different
app, or not at all. It can return PROCEED, DEFER, or CANCEL (and initiate
a new navigation to the redirect target in an app window).
Upon successful navigation, the process sets up
WebAppLaunchNavigationHandleUserData on the navigation handle. This data is
used to:
window.launchQueue).On destruction of NavigationCapturingProcess, metrics are recorded detailing
the outcome of the initial capture and redirection.
Several content::NavigationThrottle implementations exist to route links and
navigations for web apps. Their enablement status on Stable varies by platform
and feature flags:
NavigationCapturingProcess.
kPwaNavigationCapturing flag). Disabled by default on ChromeOS (the
default state is set to off, but can be enabled by user preference or
settings).WebAppLinkCapturingDelegate, ChromeOsLinkCapturingDelegate) to determine
if a navigation should be intercepted and routed to an app.
NavigationCapturingProcess.
kPwaNavigationCapturing
is active).kDesktopPWAsTabStrip feature).Browser tests for navigation capturing are located in:
navigation_capturing_browser_navigator_browsertest.cc,
navigation_capturing_forced_off_browsertest.cc,
web_app_link_capturing_parameterized_browsertest.cc, etc., in
chrome/browser/web_applications/.These tests verify capturing behavior across various combinations of:
target attributes (_self, _blank).client_mode).