AEM React SPA: en.model.json (spa root) Not Updating After Child Page Publish
- en page created using SPA root template.
- home page created using SPA Page template
- The SPA loads en.model.json in the network tab.
Hi @mayursatav ,
Root Cause
In AEM SPA Editor, the *.model.json file of a SPA root page (e.g., /en) includes all child pages by design.
So, when you publish a child (like /en/home), /en.model.json remains cached and is not invalidated automatically — leading to stale data unless:
- You manually republish /en, or
- Explicit cache invalidation or re-rendering is triggered.
This is not a bug, but a default behavior of the AEM SPA model export system, which serves the whole content tree from the SPA root.
Solution:
1. Automatically Republish the SPA Root Page on Child Publish
This is the most reliable and scalable method.
Implementation Options:
Create a custom workflow process step or listener that listens to replication events (e.g., com.day.cq.replication.ReplicationAction.EVENT_TOPIC) and automatically replicates the root SPA page (e.g., /en) whenever any of its children are published.
Example:
Listen for any page under /content/mysite/us/en/*, and then trigger replication of /content/mysite/us/en.
"If a child page changes, the root model should be invalidated (or re-fetched) to reflect changes in the aggregated model tree."
2. Force Invalidate .model.json in Dispatcher or CDN
Configure the flush agent or dispatcher to invalidate:
- /en.model.json
- /en.model.json?*
- /en.infinity.json (if used)
You can do this via a custom AgentConfig or Dispatcher flush rule triggered on publish of any descendant.
Example:
# dispatcher/cache.rules
/0001 { /glob "*.model.json" /type "deny" }
/0002 { /glob "/content/mysite/us/en.model.json" /type "allow" }
/0003 { /glob "/content/mysite/us/en/*" /type "allow" }
3. Use Client-side Fetching of Child .model.json (Alternative Pattern)
If you don’t want full model hydration at root level, you can configure the SPA SDK to fetch each page's own .model.json rather than aggregating via the root.
This requires modifying the ModelManager config in the SPA (React):
ModelManager.initialize({
path: window.location.pathname + ".model.json"
});
But be careful — this breaks deep linking and SPA routing unless handled very carefully. The default root-model pattern is generally safer and better supported.
4. Prevent Double Rendering in SPA
This issue usually occurs when:
Initial model (en.model.json) contains all child pages, and
SPA route renders both current and nested components.
Fix:
Ensure your React routing is scoped strictly to path match and not rendering nested child routes unless explicitly required.
<Switch>
<Route exact path="/en" component={EnPage} />
<Route exact path="/en/home" component={HomePage} />
</Switch>
Note:
Stick with the root model approach, and use automatic replication of the root page (or its .model.json invalidation) as your scalable fix. This is used in enterprise-grade AEM SPA setups across AMS and Cloud.
Regards,
Amit
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.