Chapter 3 covers the development of SPA Model Routing to allow navigation between different views of the App. React Router and the HTML5 History API are used. A list component is used to provide dynamic navigation.

SPA Routing Approach

The high level approach to navigation with the AEM SPA Editor is to map different views within the SPA to respective pages within AEM. This makes it easy to manage multiple parts of the application and allows content authors to edit individual views. More information about the SPA Model Routing approach can be found here.

Each AEM Page represented in the App will be wrapped in a <Route> with a path of the AEM page. The psuedo code of this in JSX below:

As discussed in Chapter 1, the App is driven based on a JSON model provided by AEM. The JSON model uses a Sling Model, HierarchyPage, to include the content of multiple AEM pages with a single request. This allows for most of the content of the App to be loaded on the initial page load and should minimize subsequent server-side requests as a user navigates the app. Review the explanation about the HiearchyPage implementation in Chapter 1 for more information.

Below is a psuedo representation of the JSON exported by AEM. Notice that the JSON structure maps nicely to the above JSX structure.

Install React Router

Persona: Front End Developer

React Router provides a collection of navigational components for React applications to provide and manage different views of the application. React Router is broken into 3 modules: react-router, react-router-dom and react-router-native. Since this will be deployed to the web we will use react-router-dom. More information about React Router for the web can be found here.

Open a new terminal window and navigate to the react-app directory. Install react-router and react-router-dom:

withRoute is a reusable component that can wrap any other React component. This will primarily be used to wrap the Page component to provide routing between pages.

The Header component in the App is a sticky header and when navigation occurs to different views we want to make sure the browser scrolls to the top. The ScrollToTop component will provide that functionality. More information on scroll restoration and React Router can be found here.

Update react-app/src/index.js to wrap the App with BrowserRouter and ScrollToTop components:

BrowserRouter is a type of Router that uses the HTML5 history API to keep the App UI in sync with the URL. This allows for easy deep linking to specific views of the App. The ScrollToTop component from RouteHelper is included.

Update Page.js beneath react-app/src/components/page to wrap the WkndPage component with a route using the utility from RouteHelper.

To recap, the AEM resource wknd-events/components/structure/page represents an AEM Page and will be mapped to the React component WkndPage. With the addition of withRoute all pages will be wrapped as a Route that can then be navigated to.

List Component

Persona: Front End Developer

Next we will implement a React component to display a list of links. This React component will map to an AEM List component, which is provided by Core Components.

The List component provides an array of items that includes a url, path, optional description, title and a datetimestamp for when the page was last modified. A sample of the List JSON model can be seen below:

Instead of using a standard anchor tag the <Link> component is used from react-router-dom. This provides the look and feel of a standard HTML link but instead will use React Router to navigate to a different part of the App without a page refresh.

Lastly, add a List class to List.js that will map to the AEM component wknd-events/components/content/list. The List class expects an array named items. We will iterate over the items array and pass the properties to include multiple ListItem components.

In the AEM Sites Console update the page structure beneath /content/wknd-events/react/home to include 2 or more child pages. Use the WKND Event Page template (not WKND Event React App template). The child pages can be named however you want.

Add a List Component to the page and configure with the following values to display a list of child pages beneath the Home page:

Toggle into Preview mode and then click one of the links in the List component. You should be navigated to the child page. Once on the child page toggle back into Edit mode and you should be able to edit the components on the page.

Try the navigation and notice that the page is not refreshed and the URL is updated. The Back button in the browser also should work. As you navigate there should not be any network traffic, outside of the initial page load.

Lastly we don't have any navigation to return to the Home page (not counting the browser's back button). In the next section we will add a dynamic return button to the Header component.

Update Header Component

Persona: Front End Developer

Next we will add a back button as part of the Header component. Like the List component we will use components provided by React Router to accomplish this.

Update the Header class to remove the export default and add a new getter method named homeLink(). The homeLink() method will look at the location and determine if the current route is equal to the Home page. If it is not equal a Link to the Home page will be returned.

Start the local development server to view the updated styles of the Back button in the Header:

Add Redirect to App.js

Persona: Front End Developer

The last thing we will do in this chapter is update App.js, the entry point to the application, to automatically redirect to the Home page view.

Update react-app/src/App.js to import the Redirect component from react-router.

Add a utility function named getModelPath() to strip the extension of a url to just return the path. Add another function named canRedirectHome() to determine based on the current location if the app should redirect to the Home view.