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.
View transitions use the browser's native document.startViewTransition API to create smooth animations between different states of your application. The API works by:
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.
Angular Router integrates view transitions into the navigation lifecycle to create seamless route changes. During navigation, the Router:
startViewTransition when routes are ready for activationThe 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.
Enable view transitions by adding the withViewTransitions feature to your router configuration. Angular supports both standalone and NgModule bootstrap approaches:
import {bootstrapApplication} from '@angular/platform-browser';
import {provideRouter, withViewTransitions} from '@angular/router';
import {routes} from './app.routes';
bootstrapApplication(MyApp, {
providers: [provideRouter(routes, withViewTransitions())],
}); 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.
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:
::view-transition-old() and ::view-transition-new() selectorsHere'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
The withViewTransitions feature accepts an options object with an onViewTransitionCreated callback for advanced control over view transitions. This callback:
ViewTransitionInfo object containing: ViewTransition instance from startViewTransition
ActivatedRouteSnapshot for the route being navigated fromActivatedRouteSnapshot for the route being navigated toUse 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, isActive} from '@angular/router';
withViewTransitions({
onViewTransitionCreated: ({transition}) => {
const router = inject(Router);
const targetUrl = router.currentNavigation()!.finalUrl!;
// Skip transition if only fragment or query params change
const config = {
paths: 'exact',
matrixParams: 'exact',
fragment: 'ignored',
queryParams: 'ignored',
};
const isTargetRouteCurrent = isActive(targetUrl, router, config);
if (isTargetRouteCurrent()) {
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.
The following examples demonstrate various view transition techniques adapted from the Chrome team's documentation for use with Angular Router:
Elements can transition smoothly between different DOM elements as long as they share the same view-transition-name.
Create unique animations for elements entering and leaving the viewport during route transitions.
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."
Use view transition types to apply different animation styles based on navigation context.
This approach uses CSS classes on the transition root element to control animation styles.
Maintain other page animations during view transitions to create more dynamic user experiences.
Control view transitions programmatically using JavaScript APIs for complex animation scenarios.
Super-powered by Google ©2010–2025.
Code licensed under an MIT-style License. Documentation licensed under CC BY 4.0.
https://angular.dev/guide/routing/route-transition-animations