Expand my Community achievements bar.

Render AEM pages in React dynamically independently of URL path

Avatar

Level 1

 

I have the need to be able to render any of the pages in my AEM model.json dynamically regardless of the current URL in a SPA React app.

My AEM model.json structure has pages following the `/<country>/<language>/rest/of/path` format, but I want to be able to strip the country/language and just use the rest of the URL path.

I am able to do this when I initialize the ManagerModel with the desired path like this:

 

const path = `/path/to/<my_model>.model.json`

/* initialize the ModelManager with the path to the model.json */
ModelManager.initialize({ path })

/*
  grab the desired section of the model and render by calling ReactDOM.render
  By doing this I am able to render the section of the model that maps /us/en/user- 
 account for example, and render the correct content even though the current browser path 
 is `/`
*/
ModelManager.getData(`/us/en/<page_to_load>`).then(render)

 

When I handle navigation with `history.push` (I use react-router), I want to be able to render another page following the same logic. By default, having executed `ModelManager.getData("/us/en/<page_to_load>")`, every page that I navigate to then renders that same portion of the model.

To fix this, I have tried many variations of `ModelManager.getData()` calls with no success. The only thing that I have been able to have any success with is dynamically passing the path to the next page to render to a callback function that is defined on the index.js level and passed down as a prop to App.js. The callback triggers another ReactDOM.render call and loads the page correctly regardless of what the actual URL path is. That code looks something like this:

 

<App
  reRender={(path) => {
    /* manipulate the path so that it properly maps to the correct AEM model data */
    const updatedPath = `/us/en/${path}`
    /*
     this works, but causes another ReactDOM.render call every time that the current page 
     is changed
    */
    ModelManager.getData(updatedPath).then(render)
  }}
/>


There are also cases where the page that has been navigated to doesn't have a corresponding path in the modelStore mapping. I am able to handle that like this:

 

const pathToInsert = `/<country>/<language>/${window.location.pathname}.model.json`
ModelManager.modelStore.insertData(pathToInsert)
ModelManager.getData(pathToInsert).then(render)

/*
I have been having issues with this, but can get the newly inserted model to load properly by
re-routing back to the current path from the current path
*/

this.props.history.push(window.location.pathname)

 

I have read and re-read the documentation here and I am unable to figure out the correct way to do what I want to do. The above solutions work for the most part, but are pretty hacky and I would like to find out the proper way to accomplish this. Any help is greatly appreciated!

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

SPA
0 Replies