Managing state transitions is one of the hardest parts of building applications. This is especially true on the web, where you also need to ensure that the state is reflected in the URL. In addition, we often want to split applications into multiple bundles and load them on demand. Doing this transparently isn’t trivial. The Angular router is designed to solve these problems. Using the router, you can declaratively specify application state, manage state transitions while taking care of the URL, and load components on demand. In this article I will discuss the API of the router, as well as the mental model and the design principles behind it. Let’s get started.Outline What Do Routers Do? URL Parsing and Serialization Accessing URL Tree Route Recognition Powerful Matching Syntax Component Instantiation Using Params QueryParams and Fragment Using Snapshots Navigation Imperative Navigation RouterLink More on Syntax Navigation is URL Based, not Route Based E2E Example SummaryWhat Do Routers Do? Before we jump into the specifics of the Angular Router, let’s talk about what routers do in general. As you might know, an Angular 2 application is a tree of components. Some of these components are reusable UI components (e.g., list, table), and some are application components. The router cares about application components, or, to be more specific, about their arrangements. Let’s call such component arrangements router states. A router state defines what is visible on the screen. The router configuration defines all the potential router states an application can be in. Let’s look at an example.[ {path: ‘/team/:id’, component: TeamCmp, children: [ {path: ‘/details’, component: DetailsCmp}, {path: ‘/help’, component: HelpCmp, outlet: ‘aux’} ]}, {path: ‘/summary’, component: SummaryCmp}, {path: ‘/chat’, component: ChatCmp, outlet: ‘aux’}] which can be depicted as follows: An outlet is the location where a component will be placed. If a node has multiple children of the same color, i.e., of the same outlet type, only one of them can be active at a time. Consequently, the team and summary components cannot be displayed together. A router state is a subtree of the configuration tree. For instance, the example below has the summary component activated. The router’s primary job is to manage navigations between states, which includes updating the component tree. A navigation is essentially the act of transitioning from one activated subtree to another. Say we perform a navigation, and this is the result: Because the summary is no longer active, the router will remove it. Instead, it will instantiate the details component and display it inside the team component, with the chat component visible on the side. That’s it. The router simply allows us to express all the potential states in which our application can be, and provides a mechanism for navigating from one state to another. So now we’ve learned what routers do in general. It’s time to talk about the Angular router. The Angular router takes a URL, parses it into a URL tree, recognizes router states, instantiates all the needed components, and, finally, manages navigation. Let’s look at each one of these operations in detail.URL Parsing and Serialization The URL bar provides a huge advantage for web applications over native applications. It allows you to reference states, bookmark them, and share them with your friends. In a well-behaved web application, any application state transition results in a URL change, and any URL change results in a state transition. In other words, a URL is a serialized router state. The first thing the router does is parse the URL string into a URL tree. The router does not need to know anything about your application or its components to do that. In other words, the parse operation is application-independent. To get a feel of how this works, let’s look at a few examples. Let’s start with a simple URL consisting of three segments./team/3/details// is parsed into the following URL tree:UrlSegment(path: ‘team’, parameters: {}, outlet: primary) -> UrlSegment(path: ‘3’, parameters: {}, outlet: primary) -> UrlSegment(path: ‘details’, parameters: {}, outlet: primary) As you can see, a URL tree consists of URL segments. And each URL segment contains its parameters and its outlet name. Now look at this example, where the first segment has the extra parameter set to true./team;extra=true/3// is parsed into the following URL tree:UrlSegment(path: ‘team’, parameters: {extra: true}, outlet: primary) -> UrlSegment(path: ‘3’, parameters: {}, outlet: primary) Finally, let’s see the result when the team segment has two children instead of one./team/3(aux:/chat;open=true)// is parsed into the following URL tree:UrlSegment(path: ‘team’, parameters: {}, outlet: primary) -> UrlSegment(path: ‘3’, parameters: {}, outlet: primary) -> UrlSegment(path: ‘chat’, parameters: {open:true}, outlet: aux) As you can see, the router uses parenthesis