Goal
Adobe Experience Manager 2021.10.5933.20211012T154732Z-210900 (Oct 12, 2021)
This post is on making necessary changes in React SPA generated by the maven archetype (https://github.com/adobe/aem-project-archetype) to shorten the URLs eg. /content/eaem-spa-short-urls/us/en/home.html to /us/en/home.html
For Vanity urls check this post
Solution
1) Create the React SPA maven project using following command...
mvn -B archetype:generate -D archetypeGroupId=com.adobe.aem -D archetypeArtifactId=aem-project-archetype -D archetypeVersion=31 -D aemVersion=cloud -D appTitle="Experience AEM Short URLs" -D appId="eaem-spa-short-urls" -D groupId="apps.experienceaem.sites" -D frontendModule=react -D includeExamples=n -D includeDispatcherConfig=n
2) Create script eaem-spa-short-urls\ui.frontend\src\components\appConstants.js with the following code to give App root url...
export const PROJECT_URL_ROOT = "/content/eaem-spa-short-urls";
3) Adjust Router code to add the shortened URL in eaem-spa-short-urls\ui.frontend\src\components\RouteHelper\RouteHelper.js
import React, {Component} from 'react'; import {Route} from 'react-router-dom'; import {AuthoringUtils} from "@adobe/aem-spa-page-model-manager"; import {PROJECT_URL_ROOT} from "../appConstants"; export const withRoute = (WrappedComponent, extension) => { return class CompositeRoute extends Component { render() { let routePath = this.props.cqPath; if (!routePath) { return <WrappedComponent {...this.props} />; } extension = extension || 'html'; let paths = ['(.*)' + routePath + '(.' + extension + ')?']; if (!AuthoringUtils.isInEditor() && routePath.startsWith(PROJECT_URL_ROOT)) { paths.push(routePath.substring(PROJECT_URL_ROOT.length) + ".html"); } console.log(paths); // Context path + route path + extension return ( <Route key={routePath} exact path={ paths } render={routeProps => { return <WrappedComponent {...this.props} {...routeProps} />; }} /> ); } }; };
4) Adjust the code in Navigation components to create links to shortened urls eg. eaem-spa-short-urls\ui.frontend\src\components\Nav\Nav.js
class NavItem extends Component { render() { if(!this.props.path || !this.props.title || !this.props.url) { return null; } let url = this.props.url; url = url.substring(PROJECT_URL_ROOT.length); return ( <li className="NavItem" key={this.props.path}> <Link className="NavItem-link" to={url}> {this.props.title} </Link> </li> ); } }
5) Under the hood, app makes calls to AEM for the model.json eg. /content/eaem-spa-short-urls/us/en.model.json, however due to the shortened url it makes additional call for fetching the model.json using shortened one eg. us/en.model.json. To snub this additional request to server, extend the ModelClient, creating ShortURLModelClient in eaem-spa-short-urls\ui.frontend\src\index.js and ignore such requests....
class ShortURLModelClient extends ModelClient { fetch(modelPath) { //if the path does not start with /content (page editing) or /conf (template editing) return empty model if (modelPath && !/^\/content|^\/conf/.test(modelPath)) { return Promise.resolve({}); } else { return super.fetch(modelPath); } } } const modelManagerOptions = {}; if (process.env.REACT_APP_PROXY_ENABLED) { modelManagerOptions.modelClient = new LocalDevModelClient(process.env.REACT_APP_API_HOST); } else { modelManagerOptions.modelClient = new ShortURLModelClient(process.env.REACT_APP_API_HOST); }
6) For handling the Resource mapping of URL eg. /us/en/home.html and do an internal redirect to the real url eg. /content/eaem-spa-short-urls/us/en/home.html, create the following etc/map entries (there are many ways to handle redirects; on publish generally the preferred way is to use dispatcher rewrites, dispatcher/src/conf.d/rewrites/rewrite.rules). However to keep things simple, adding an etc/map entry in eaem-spa-short-urls\ui.content\src\main\content\jcr_root\etc\map\https\author-p10961-e90064\.content.xml
<?xml version="1.0" encoding="UTF-8"?> <jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:sling="http://sling.apache.org/jcr/sling/1.0" jcr:primaryType="sling:Mapping" sling:internalRedirect="/content/eaem-spa-short-urls/us/" sling:match="author-p10961-e90064.adobeaemcloud.com/us/"/>
No comments:
Post a Comment