Recently, I’ve been involved in building a SPA with AEM using AngularJS(1.x). I intent to make this article address the typical architectural concerns when integrating AEM with SPA frameworks.
Before you proceed – Hang on! – Read about SPA and round up on SPA frameworks.
AUTHORING
Why think again. Serve the authors full page (no SPA) in author instance. Authoring is AEM’s strength. We cannot afford to make any behavioural change there. Leverage the WCMMODE information to compose the pages into SPA experience only in publish instance. Achieve this making conditional inclusion in templates.
Why think again. Serve the authors full page (no SPA) in author instance. Authoring is AEM’s strength. We cannot afford to make any behavioural change there. Leverage the WCMMODE information to compose the pages into SPA experience only in publish instance. Achieve this making conditional inclusion in templates.
TEMPLATES
In the eyes of SPA (JS) frameworks, there are 2 types of templates –
In the eyes of SPA (JS) frameworks, there are 2 types of templates –
- Layout template – One index page that gets loaded first and usually contains the invariable content such as header and footer with the placeholder for the partial template.
- Partial template – Rest all pages are partial, usually contains body content, the variable portion that gets sandwiched into the layout templates’s placeholder.
/content/example/en.html - Provides the layout template (full html page with a placeholder for the variable content) for the SPA framework. /content/example/en.partial.html - Provides the partial template(just the body content) for a SPA framework.
<!--author--> <sly data-sly-test="${!wcmmode.disabled}"><sly data-sly-include="partial.html" data-sly-unwrap/></sly> <!--publish--> <sly data-sly-test="${wcmmode.disabled}"><div ng-view></div></sly>
Code page component backing the template to support the above. For SPA framework’s following component tree model, the layout template is the root component which app gets bootstrapped with .
COMPONENTS
In AEM, component represents a visually cohesive portion of page. Find its counterpart in SPA framework. Depending on the SPA framework being chosen , it could be –
In AEM, component represents a visually cohesive portion of page. Find its counterpart in SPA framework. Depending on the SPA framework being chosen , it could be –
- a view, meaning a html markup backed by view model or controller. Example – AngularJS, Vue, etc. This translates to AEM component having a htl (sightly) file and a clientlib with controller (JS).
- a component in SPA framework which is essentially an enhanced HTML vocabulary. Example – React, Angular, Vue, etc. This translates to AEM component having a clientlib with component file (js) and often with a htl expressed with SPA specific and other component tags.
URL AND ROUTES
SPA’s usually follow hashbang url style. http://www.example.com/#content/example/en
Often HTML5 history APIs could be leveraged to make it look like usual URL. The hash section in the url is called route. And yes, the SPA framework is in charge of routing. Hence, there has to be a match making between the site content hierarchy and the routes. An example route using AngularJS is shown below.
SPA’s usually follow hashbang url style. http://www.example.com/#content/example/en
Often HTML5 history APIs could be leveraged to make it look like usual URL. The hash section in the url is called route. And yes, the SPA framework is in charge of routing. Hence, there has to be a match making between the site content hierarchy and the routes. An example route using AngularJS is shown below.
$routeProvider.when('/content/example/:name*', {
templateUrl: function(attr) {
var url = '/content/example/' + attr + '.partial.html';
}
return url;
}
}).when('/home', {
//For home page
templateUrl: '/content/example/en.partials.html'
}).when('/', {
redirectTo: '/home'
}).otherwise({
//If not matching with above criteria, redirect to 404 page.
redirectTo: '/content/example/en/errors/404'
});
LINKS
Every time an author choose a link, we’ve to make it to DOM as-is in author mode and translate to hashbang style in publish mode. This asks for changes in RTE link plugin too.
if (link.startsWith('/content')) {
if (link.indexOf('/content/dam') === -1) {
if (wcmMode === 'wcm-enabled') {
// Author mode - Append .html if absent.
if (link.indexOf('.html') === -1) {
url = link + '.html';
}
} else {
// Publish mode - Hashbang style url.
url = '#' + link;
}
}
ACCESS CONTROL
If there are protected (CUG) pages, you have to be concerned about this. SPA framework’s cannot deal the 302 redirects usually done by sever when accessing protected page in an unauthenticated session as the browser natively redirect the page to the given url. So, we’ve to make SPA framework routing play a role here too. If certain route is protected, check the authentication state of the user and show the login page if not authenticated.
CACHING
It boils down to the design. Better way handle this is to make all the htmls 100% cacheable and any dynamic information required to be exposed as REST style APIs. This API could come from AEM or other 3rd party systems, even CORS too.
It boils down to the design. Better way handle this is to make all the htmls 100% cacheable and any dynamic information required to be exposed as REST style APIs. This API could come from AEM or other 3rd party systems, even CORS too.
APPLICATION STATE
Since the SPA framework being used is in charge of the application, it has to maintain the state. Application-wide state could be anything such as locale information, logged-in state, etc. State of individual business logic are usually encapsulated into services. It often gets easier as your code has to be concerned about just one user.
BROWSER SIDE INTEGRATIONS
Usual style with SPA is to achieve integrations at the browser side, mostly with data APIs. Rich set of libraries with SPAs make integrations easier. Often sessions too are managed with data APIs.
CODE AND SKILL SET
Typically AEM projects for SPA involve a good amount of JavaScript code and hence onboard full-stack developers. JSLint becomes inevitable. We cannot let unit JS unit testing go too.
Typically AEM projects for SPA involve a good amount of JavaScript code and hence onboard full-stack developers. JSLint becomes inevitable. We cannot let unit JS unit testing go too.
No comments:
Post a Comment
If you have any doubts or questions, please let us know.