In-depth Guides
Routing

Route transition animations

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:

  1. Capturing the current state - The browser takes a screenshot of the current page
  2. Executing the DOM update - Your callback function runs to update the DOM
  3. Capturing the new state - The browser captures the updated page state
  4. 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:

  1. Completes navigation preparation - Route matching, lazy loading, guards, and resolvers execute
  2. Initiates the view transition - Router calls startViewTransition when routes are ready for activation
  3. Updates the DOM - Router activates new routes and deactivates old ones within the transition callback
  4. 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:

  1. Add view-transition-name - Assign unique names to elements you want to animate
  2. Define global animations - Create CSS animations in your global styles
  3. 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:

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.