Skip to content

Upgrading @angular/router 15 to 16

Breaking15.2.10 → 16.2.12Breaking38Security1Platform5Deprecated8New45Changed6Fixed152Other3

BreakingUpgrade verdict

35 breaking changes and 4 platform requirement changes and a security fix.

  • The tool that made older libraries built for the old compiler work with newer Angular is gone.
  • Removes the deprecated EventManager method addGlobalEventListener.
  • Removes the deprecated XhrFactory export from the http entrypoint.
  • Code that read the factories property on IterableDiffers will no longer compile or work.
Top 5 of 48 that need code or config changes

Node.js requirement changed in 16.0.0-rc.0: ^14.20.0 || ^16.13.0 || >=18.10.0 → ^16.14.0 || >=18.10.0.

Breaking35
Removes the Angular Compatibility Compiler (ngcc).
ngcc
Removes the deprecated EventManager method addGlobalEventListener.
EventManageraddGlobalEventListener
Removes the deprecated XhrFactory export from the http entrypoint.
XhrFactory
Drops the public factories property for IterableDiffers.
IterableDiffersfactories
Drops support for zone.js versions <=0.12.0.
zone.js
Removes entryComponents.
entryComponents
Removes the ReflectiveInjector symbol.
ReflectiveInjector
Adds a migration to remove Router guard and resolver interfaces.
Router
Removes the deprecated BrowserTransferStateModule symbol.
BrowserTransferStateModule
Renames provideServerSupport to provideServerRendering.
provideServerSupportprovideServerRendering
Removes the renderApplication overload that accepts a component.
renderApplication
Removes the deprecated renderModuleFactory.
renderModuleFactory
Removes deprecated ComponentFactoryResolver from APIs.
ComponentFactoryResolver
Removes RouterEvent from the Event union type.
RouterEventEvent
Removes Angular Compatibility Compiler (ngcc), so Angular View Engine libraries no longer work.
ngcc
Changes Angular Package Format: removes FESM2015, replaces ES2020 with ES2022 and FESM2020 with FESM2022.
FESM2015ES2020ES2022FESM2020FESM2022
Removes deprecated XhrFactory export from @angular/common/http; use the one from @angular/common.
XhrFactory
Deletes entryComponents from @NgModule and @Component and removes ANALYZE_FOR_ENTRY_COMPONENTS token.
entryComponents@NgModule@ComponentANALYZE_FOR_ENTRY_COMPONENTS
Removes ComponentFactoryResolver from Router APIs; use ViewContainerRef.createComponent without a factory resolver.
ComponentFactoryResolverViewContainerRef.createComponent
Removes the ReflectiveInjector and related symbols; use Injector.create to create an injector instead.
ReflectiveInjectorInjector.create
Removes the deprecated BrowserTransferStateModule; TransferState can be injected without providing the module.
BrowserTransferStateModuleTransferState
Removes the ReflectiveInjector symbol.
ReflectiveInjector
renderApplication no longer accepts a root component as its first argument; pass a bootstrapping function returning Promise<ApplicationRef> instead.
renderApplicationApplicationRefbootstrapApplication
The APP_ID token value is no longer randomly generated; bootstrapping multiple applications on one page now requires providing APP_ID yourself.
APP_IDbootstrapApplication
Removes renderModuleFactory; use renderModule instead.
renderModuleFactoryrenderModule
Removes Node.js v14 support; Node.js v16 and v18 remain officially supported.
Removes Node.js v14 support.
RendererType2.styles no longer accepts nested arrays.
RendererType2.styles
Provides MockPlatformLocation by default in tests, which may break tests relying on BrowserPlatformLocation.
MockPlatformLocationBrowserPlatformLocationPlatformLocationLocation.getState()TestBed.configureTestingModule
Makes ngTemplateOutletContext mismatches a compile-time error.
ngTemplateOutletContextNgTemplateOutletTemplateRef
QueryList.filter now narrows types with type guard functions, which may require application code updates.
QueryList.filter
The Scroll event's routerEvent property may now also be a NavigationSkipped event, not only NavigationEnd.
ScrollrouterEventNavigationSkippedNavigationEnd
Users using SSR with JIT mode must now add import to @angular/compiler before bootstrapping the application.
@angular/compiler
ComponentRef.setInput only sets the input when the new value differs from the previous one based on Object.is equality.
ComponentRef.setInputObject.is
Router.createUrlTree now handles more scenarios correctly, which may change behavior of tests with invalid ActivatedRoute mocks.
ActivatedRouteRouter.createUrlTreerouter.navigate
Security1
Changes URL sanitization to only block javascript: URLs.
Platform4
Adds support for TypeScript 5.1.
Adds support for TypeScript 5.1.
Drops support for TypeScript 4.8.
Removes Node.js v14 support.
Deprecated8
Introduces runInInjectionContext and deprecates the prior version.
runInInjectionContext
Deprecates the moduleId @Component property.
moduleId@Component
Deprecates the withServerTransition call.
withServerTransition
Deprecates useAbsoluteUrl and baseUrl.
useAbsoluteUrlbaseUrl
makeStateKey, StateKey and TransferState move from @angular/platform-browser to @angular/core.
makeStateKeyStateKeyTransferState
Deprecates the @Directive/@Component moduleId property, which will be removed in v17.
moduleId@Directive@Component
Deprecates the platform-server PlatformConfig.baseUrl and PlatformConfig.useAbsoluteUrl options as unused.
PlatformConfig.baseUrlPlatformConfig.useAbsoluteUrl
ApplicationConfig has moved; import it from @angular/core instead.
ApplicationConfig@angular/core

Generated by DepDelta from published .d.ts files. Not mixed with prose notes.

  • removed: function ɵflatten<T>(arr: T[][]): T[]
  • removed: function ɵwithPreloading(preloadingStrategy: Type<PreloadingStrategy>): PreloadingFeature
  • removed: get RouterLink.preserveFragment(): boolean
  • removed: get RouterLink.replaceUrl(): boolean
  • removed: get RouterLink.skipLocationChange(): boolean
  • removed: get RouterLinkWithHref.preserveFragment(): boolean
  • removed: get RouterLinkWithHref.replaceUrl(): boolean
  • removed: get RouterLinkWithHref.skipLocationChange(): boolean
  • removed: method RouterOutletContract.activateWith(activatedRoute: ActivatedRoute, resolver: ComponentFactoryResolver | null): void
  • removed: property OutletContext.resolver: ComponentFactoryResolver | null
  • removed: set RouterLink.preserveFragment(preserveFragment: boolean | string | null | undefined)
  • removed: set RouterLink.replaceUrl(replaceUrl: boolean | string | null | undefined)
  • removed: set RouterLink.skipLocationChange(skipLocationChange: boolean | string | null | undefined)
  • removed: set RouterLinkWithHref.preserveFragment(preserveFragment: boolean | string | null | undefined)
  • removed: set RouterLinkWithHref.replaceUrl(replaceUrl: boolean | string | null | undefined)
  • removed: set RouterLinkWithHref.skipLocationChange(skipLocationChange: boolean | string | null | undefined)
  • changed: constructor Scroll(routerEvent: NavigationEnd, position: [number, number] | null, anchor: string | null) → constructor Scroll(routerEvent: NavigationEnd | NavigationSkipped, position: [number, number] | null, anchor: string | null)
  • changed: function ɵafterNextNavigation(router: Router, action: () => void): void → function ɵafterNextNavigation(router: { events: Observable<Event_2> }, action: () => void): void
  • changed: method RouterOutlet.activateWith(activatedRoute: ActivatedRoute, resolverOrInjector?: ComponentFactoryResolver | EnvironmentInjector | null): void → method RouterOutlet.activateWith(activatedRoute: ActivatedRoute, environmentInjector?: EnvironmentInjector | null): void
  • changed: readonly property Scroll.routerEvent: NavigationEnd → readonly property Scroll.routerEvent: NavigationEnd | NavigationSkipped
  • changed: static property RouterLink.ɵdir: i0.ɵɵDirectiveDeclaration<RouterLink, '[routerLink]', never, { 'target': 'target'; 'queryParams': 'queryParams'; 'fragment': 'fragment'; 'queryParamsHandling': 'queryParamsHandling'; 'state': 'state'; 'relativeTo': 'relativeTo'; 'preserveFragment': 'preserveFragment'; 'skipLocationChange': 'skipLocationChange'; 'replaceUrl': 'replaceUrl'; 'routerLink': 'routerLink… → static property RouterLink.ɵdir: i0.ɵɵDirectiveDeclaration<RouterLink, '[routerLink]', never, { 'target': { 'alias': 'target'; 'required': false }; 'queryParams': { 'alias': 'queryParams'; 'required': false }; 'fragment': { 'alias': 'fragment'; 'required': false }; 'queryParamsHandling': { 'alias': 'queryParamsHandling'; 'required': false }; 'state': { 'alias': 'state'; 'required': false }; 'rela…
  • changed: static property RouterLinkActive.ɵdir: i0.ɵɵDirectiveDeclaration<RouterLinkActive, '[routerLinkActive]', ['routerLinkActive'], { 'routerLinkActiveOptions': 'routerLinkActiveOptions'; 'ariaCurrentWhenActive': 'ariaCurrentWhenActive'; 'routerLinkActive': 'routerLinkActive' }, { 'isActiveChange': 'isActiveChange' }, ['links'], never, true, never> → static property RouterLinkActive.ɵdir: i0.ɵɵDirectiveDeclaration<RouterLinkActive, '[routerLinkActive]', ['routerLinkActive'], { 'routerLinkActiveOptions': { 'alias': 'routerLinkActiveOptions'; 'required': false }; 'ariaCurrentWhenActive': { 'alias': 'ariaCurrentWhenActive'; 'required': false }; 'routerLinkActive': { 'alias': 'routerLinkActive'; 'required': false } }, { 'isActiveChange': 'isActiv…
  • changed: static property RouterLinkWithHref.ɵdir: i0.ɵɵDirectiveDeclaration<RouterLink, '[routerLink]', never, { 'target': 'target'; 'queryParams': 'queryParams'; 'fragment': 'fragment'; 'queryParamsHandling': 'queryParamsHandling'; 'state': 'state'; 'relativeTo': 'relativeTo'; 'preserveFragment': 'preserveFragment'; 'skipLocationChange': 'skipLocationChange'; 'replaceUrl': 'replaceUrl'; 'routerLink': 'ro… → static property RouterLinkWithHref.ɵdir: i0.ɵɵDirectiveDeclaration<RouterLink, '[routerLink]', never, { 'target': { 'alias': 'target'; 'required': false }; 'queryParams': { 'alias': 'queryParams'; 'required': false }; 'fragment': { 'alias': 'fragment'; 'required': false }; 'queryParamsHandling': { 'alias': 'queryParamsHandling'; 'required': false }; 'state': { 'alias': 'state'; 'required': false…
  • changed: static property RouterOutlet.ɵdir: i0.ɵɵDirectiveDeclaration<RouterOutlet, 'router-outlet', ['outlet'], { 'name': 'name' }, { 'activateEvents': 'activate'; 'deactivateEvents': 'deactivate'; 'attachEvents': 'attach'; 'detachEvents': 'detach' }, never, never, true, never> → static property RouterOutlet.ɵdir: i0.ɵɵDirectiveDeclaration<RouterOutlet, 'router-outlet', ['outlet'], { 'name': { 'alias': 'name'; 'required': false } }, { 'activateEvents': 'activate'; 'deactivateEvents': 'deactivate'; 'attachEvents': 'attach'; 'detachEvents': 'detach' }, never, never, true, never>
  • changed: type Event = RouterEvent | NavigationStart | NavigationEnd | NavigationCancel | NavigationError | RoutesRecognized | GuardsCheckStart | GuardsCheckEnd | RouteConfigLoadStar… → type Event = NavigationStart | NavigationEnd | NavigationCancel | NavigationError | RoutesRecognized | GuardsCheckStart | GuardsCheckEnd | RouteConfigLoadStart | RouteConfi…
  • changed: type RouterFeatures = PreloadingFeature | DebugTracingFeature | InitialNavigationFeature | InMemoryScrollingFeature | RouterConfigurationFeature | NavigationErrorHandlerFeature → type RouterFeatures = PreloadingFeature | DebugTracingFeature | InitialNavigationFeature | InMemoryScrollingFeature | RouterConfigurationFeature | NavigationErrorHandlerFeature | Co…
  • added: function mapToCanActivate(providers: Array<Type<{ canActivate: CanActivateFn }>>): CanActivateFn[]
  • added: function mapToCanActivateChild(providers: Array<Type<{ canActivateChild: CanActivateChildFn }>>): CanActivateChildFn[]
  • added: function mapToCanDeactivate<T = unknown>(providers: Array<Type<{ canDeactivate: CanDeactivateFn<T> }>>): CanDeactivateFn<T>[]
  • added: function mapToCanMatch(providers: Array<Type<{ canMatch: CanMatchFn }>>): CanMatchFn[]
  • added: function mapToResolve<T>(provider: Type<{ resolve: ResolveFn<T> }>): ResolveFn<T>
  • added: function withComponentInputBinding(): ComponentInputBindingFeature
  • added: function ɵloadChildren(route: Route, compiler: Compiler, parentInjector: Injector, onLoadEndListener?: (r: Route) => void): Observable<LoadedRouterConfig>
  • added: get Router.lastSuccessfulNavigation(): Navigation | null
  • added: property ExtraOptions.bindToComponentInputs?: boolean
  • added: property RouterLink.preserveFragment: boolean
  • added: property RouterLink.replaceUrl: boolean
  • added: property RouterLink.skipLocationChange: boolean
  • added: property RouterLinkWithHref.preserveFragment: boolean
  • added: property RouterLinkWithHref.replaceUrl: boolean
  • added: property RouterLinkWithHref.skipLocationChange: boolean
  • added: readonly property Router.componentInputBindingEnabled: boolean
  • added: readonly property RouterOutlet.supportsBindingToComponentInputs = true
  • added: readonly property RouterOutletContract.supportsBindingToComponentInputs?: true
  • added: static property RouterLink.ngAcceptInputType_preserveFragment: unknown
  • added: static property RouterLink.ngAcceptInputType_replaceUrl: unknown
  • added: static property RouterLink.ngAcceptInputType_skipLocationChange: unknown
  • added: static property RouterLinkWithHref.ngAcceptInputType_preserveFragment: unknown
  • added: static property RouterLinkWithHref.ngAcceptInputType_replaceUrl: unknown
  • added: static property RouterLinkWithHref.ngAcceptInputType_skipLocationChange: unknown
  • added: readonly property RouterTestingHarness.fixture: ComponentFixture<unknown>