Routing and state management in the JSS Angular sample app

Current version: 20.x

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.

Do you have some feedback for us?

If you have suggestions for improving this article,