Route transition animations enhance user experience by providing smooth visual transitions when navigating between different views in your Angular application. Angular Router includes built-in support for the browser's View Transitions API, enabling seamless animations between route changes in supported browsers.
HELPFUL: The Router's native View Transitions integration is currently in developer preview. Native View Transitions are a relatively new browser feature with limited support across all browsers.
How View Transitions work
View transitions use the browser's native document.startViewTransition
API to create smooth animations between different states of your application. The API works by:
- Capturing the current state - The browser takes a screenshot of the current page
- Executing the DOM update - Your callback function runs to update the DOM
- Capturing the new state - The browser captures the updated page state
- Playing the transition - The browser animates between the old and new states
Here's the basic structure of the startViewTransition
API:
document.startViewTransition(async () => { await updateTheDOMSomehow();});
For more details about the browser API, see the Chrome Explainer.
How the Router uses view transitions
Angular Router integrates view transitions into the navigation lifecycle to create seamless route changes. During navigation, the Router:
- Completes navigation preparation - Route matching, lazy loading, guards, and resolvers execute
- Initiates the view transition - Router calls
startViewTransition
when routes are ready for activation - Updates the DOM - Router activates new routes and deactivates old ones within the transition callback
- Finalizes the transition - The transition Promise resolves when Angular completes rendering
The Router's view transition integration acts as a progressive enhancement. When browsers don't support the View Transitions API, the Router performs normal DOM updates without animation, ensuring your application works across all browsers.
Enabling View Transitions in the Router
Enable view transitions by adding the withViewTransitions
feature to your router configuration. Angular supports both standalone and NgModule bootstrap approaches:
Standalone bootstrap
import { bootstrapApplication } from '@angular/platform-browser';import { provideRouter, withViewTransitions } from '@angular/router';import { routes } from './app.routes';bootstrapApplication(MyApp, { providers: [ provideRouter(routes, withViewTransitions()), ]});
NgModule bootstrap
import { NgModule } from '@angular/core';import { RouterModule } from '@angular/router';@NgModule({ imports: [RouterModule.forRoot(routes, {enableViewTransitions: true})]})export class AppRouting {}
Try the "count" example on StackBlitz
This example demonstrates how router navigation can replace direct startViewTransition
calls for counter updates.
Customizing transitions with CSS
You can customize view transitions using CSS to create unique animation effects. The browser creates separate transition elements that you can target with CSS selectors.
To create custom transitions:
- Add view-transition-name - Assign unique names to elements you want to animate
- Define global animations - Create CSS animations in your global styles
- Target transition pseudo-elements - Use
::view-transition-old()
and::view-transition-new()
selectors
Here's an example that adds a rotation effect to a counter element:
/* Define keyframe animations */@keyframes rotate-out { to { transform: rotate(90deg); }}@keyframes rotate-in { from { transform: rotate(-90deg); }}/* Target view transition pseudo-elements */::view-transition-old(count),::view-transition-new(count) { animation-duration: 200ms; animation-name: -ua-view-transition-fade-in, rotate-in;}::view-transition-old(count) { animation-name: -ua-view-transition-fade-out, rotate-out;}
IMPORTANT: Define view transition animations in your global styles file, not in component styles. Angular's view encapsulation scopes component styles, which prevents them from targeting the transition pseudo-elements correctly.
Try the updated “count” example on StackBlitz
Advanced transition control with onViewTransitionCreated
The withViewTransitions
feature accepts an options object with an onViewTransitionCreated
callback for advanced control over view transitions. This callback:
- Runs in an injection context
- Receives a
ViewTransitionInfo
object containing:- The
ViewTransition
instance fromstartViewTransition
- The
ActivatedRouteSnapshot
for the route being navigated from - The
ActivatedRouteSnapshot
for the route being navigated to
- The
Use this callback to customize transition behavior based on navigation context. For example, you can skip transitions for specific navigation types:
import { inject } from '@angular/core';import { Router, withViewTransitions } from '@angular/router';withViewTransitions({ onViewTransitionCreated: ({transition}) => { const router = inject(Router); const targetUrl = router.getCurrentNavigation()!.finalUrl!; // Skip transition if only fragment or query params change const config = { paths: 'exact', matrixParams: 'exact', fragment: 'ignored', queryParams: 'ignored', }; if (router.isActive(targetUrl, config)) { transition.skipTransition(); } },})
This example skips the view transition when navigation only changes the URL fragment or query parameters (such as anchor links within the same page). The skipTransition()
method prevents the animation while still allowing the navigation to complete.
Examples from the Chrome explainer adapted to Angular
The following examples demonstrate various view transition techniques adapted from the Chrome team's documentation for use with Angular Router:
Transitioning elements don't need to be the same DOM element
Elements can transition smoothly between different DOM elements as long as they share the same view-transition-name
.
Custom entry and exit animations
Create unique animations for elements entering and leaving the viewport during route transitions.
Async DOM updates and waiting for content
Angular Router prioritizes immediate transitions over waiting for additional content to load.
NOTE: Angular Router does not provide a way to delay view transitions. This design choice prevents pages from becoming non-interactive while waiting for additional content. As the Chrome documentation notes: "During this time, the page is frozen, so delays here should be kept to a minimum…in some cases it's better to avoid the delay altogether, and use the content you already have."
Handle multiple view transition styles with view transition types
Use view transition types to apply different animation styles based on navigation context.
Handle multiple view transition styles with a class name on the view transition root (deprecated)
This approach uses CSS classes on the transition root element to control animation styles.
Transitioning without freezing other animations
Maintain other page animations during view transitions to create more dynamic user experiences.
Animating with JavaScript
Control view transitions programmatically using JavaScript APIs for complex animation scenarios.
Alternative: Angular Animations
If you need broader browser support or more granular control over animations, you can use the @angular/animations
package instead of native view transitions. Angular's animation system works with router state changes and provides:
- Universal browser support - Works across all browsers that support Angular
- Fine-grained control - Define complex animation sequences and timing
- Router integration - Create animations based on route changes, URL patterns, or
ActivatedRoute
data
Learn more about creating route-based animations with animation triggers and transitions.