Routing and state management in the JSS Angular sample app

Version:

The sample app uses dynamic routing based on the Layout Service (or local route data files in disconnected mode) and uses route/navigation changes to trigger app state changes. Tracing the primary execution flow must begin with the route configuration.

Client-side routing

Client-side routing occurs in the web browser. The following describes the client-side routing flow:

  • A route change (or initial load) triggers Angular routing, configured in src/app/routing/routing.module.ts.
  • Most URLs fall through to the JSS catch-all route, which is needed because the local application is not aware of all the potential routes (items/pages) configured in Sitecore.
  • The catch-all route is configured with a matcher rather than a path, specifically the jssRouteMatcher function. This function uses the JssRouteBuilderService to attempt to parse the URL as a Sitecore-formatted route, /[language]/then/the/item/path/.
  • The jssRouteMatcher function returns the language and serverRoute parameters, which are then provided to the configured route resolver, JssRouteResolver.
  • JssRouteResolver first invokes changeRoute on the JssContextService.
  • JssContextService on the client-side retrieves the route from one of the following:
    • If running in Integrated or Headless server-side rendering (SSR) mode immediately following a server render, an attempt is made to obtain route data from the TransferState, which must contain the server-side rendering state. When this occurs, the HTTP call to layout service is skipped.
    • In all other cases, the route data is fetched through an HTTP call to the Sitecore Layout Service.
  • The JssContextService retains the current route state, and returns it to the JssRouteResolver. The route resolver performs routines necessary for Experience Editor support.
  • Finally, the configured route component (defined in routing.module.ts, defaults to app/routing/layout/layout.component.ts) is loaded into the router-outlet defined in src/app/app.component.ts and is provided with the data from the route resolver. This layout component is responsible for:
    • Handling the UI for data fetching errors, such as HTTP 404s and 500s.
    • Updating route-level states, such as the page title or other meta fields.
    • Updating route-level states, such as the page title or other meta fields.

Server-side routing and data transfer

When the Angular app is prerendered by a Node server, it returns HTML to the client in the initial response. This means that the route data flow is similar to the client-side routing but has a few key differences.

The following describes how the server-side route data flow differs from the client-side routing:

  • The first step varies based on application mode:
    • In integrated mode only, Sitecore receives the request, parses the route server-side, and determines whether the requested item is handled by a JSS application, and which bundle to run.
    • In headless mode only, the Node SSR proxy receives a request and passes it on to a Sitecore layout service.
  • The Node host invokes the renderView function in the server.bundle.ts artifact. The function arguments include the route data/Layout Service output.
  • The renderView function uses Angular SSR to render the application, with two key differences in its module initialization:
    • The app uses the AppServerModule that provides server-specific implementations of some services.
    • The initial route state is injected through dependency injection using a JSS_SERVER_TO_SSR injection token.
  • Routing executes server-side and invokes the server-side implementation of JssService.
  • The JssServerService returns the route data from the JSS_SERVER_TO_SSR injection token and also places the data in TransferState for reading on the client-side.
  • Route rendering continues as it does on the client.
If you have suggestions for improving this article, let us know!