Expand my Community achievements bar.

Radically easy to access on brand approved content for distribution and omnichannel performant delivery. AEM Assets Content Hub and Dynamic Media with OpenAPI capabilities is now GA.

AEM Cloudservice - React SPA with Sling Vanity URLs | AEM Community Blog Seeding

Avatar

Administrator

BlogImage.jpg

AEM Cloudservice - React SPA with Sling Vanity URLs by Sreekanth Choudry Nalabotu

Abstract

Goal
Adobe Experience Manager 2021.9.5899.20210929T093525Z-210800 (Sep 29, 2021)

Create a AEM React SPA supporting Vanity Urls. Otb Vanity Urls are added in Page Properties, saved as jcr:content/sling:vanityPath

Solution
1) Add the function getVanityUrls() to get the list of vanity urls using querybuilder before loading the app. VanityURLModelClient extending ModelClient was added as a workaround to not request model.json using the vanity url (eg. this is invalid request http://localhost:4502/eaem-home.model.json). Code in eaem-spa-vanity-urls\ui.frontend\src\index.js facilitates loading of vanity urls into the app...


import 'react-app-polyfill/stable';
import 'react-app-polyfill/ie9';
import 'custom-event-polyfill';

import { Constants, ModelManager } from '@adobe/aem-spa-page-model-manager';
import { createBrowserHistory } from 'history';
import React from 'react';
import { render } from 'react-dom';
import { Router } from 'react-router-dom';
import {ModelClient} from '@adobe/aem-spa-page-model-manager';
import App from './App';
import LocalDevModelClient from './LocalDevModelClient';
import './components/import-components';
import './index.css';

const getVanityUrls = async () => {
const QUERY = "/bin/querybuilder.json?path=/content/eaem-spa-vanity-urls&property=jcr:content/sling:vanityPath&property.operation=exists" +
"&p.hits=selective&p.properties=jcr:content/sling:vanityPath%20jcr:path&type=cq:Page";

const response = process.env.REACT_APP_PROXY_ENABLED ? await fetch(QUERY, {
credentials: 'same-origin',
headers: {
'Authorization': process.env.REACT_APP_AEM_AUTHORIZATION_HEADER
}
}): await fetch(QUERY);

const data = (await response.json()).hits.reduce((current, next) => {
return { ...current, ...{ [next["jcr:path"]]: next["jcr:content"]?.["sling:vanityPath"] } }
}, {});

return data;
};

class VanityURLModelClient 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 VanityURLModelClient(process.env.REACT_APP_API_HOST);
}

const renderApp = (vanityUrls) => {
ModelManager.initialize(modelManagerOptions).then(pageModel => {
const history = createBrowserHistory();
render(


,
document.getElementById('spa-root')
);
});
};

document.addEventListener('DOMContentLoaded', () => {
getVanityUrls().then((vanityUrls) => {
renderApp(vanityUrls);
}, (err) => {
console.log("Error getting vanity urls", err);
renderApp({});
});
});


2) Pass the page full url to vanity url mapping object loaded in step above to child pages in eaem-spa-vanity-urls\ui.frontend\src\App.js

Read Full Blog

AEM Cloudservice - React SPA with Sling Vanity URLs

Q&A

Please use this thread to ask the related questions.



Kautuk Sahni
0 Replies