AEM Best Practices

 

This article talks about best practices which we can follow while implementing AEM project, I feel like it is an ongoing task so, whenever I see something new I will update the post immediately, as I am planning to publish separate article on sightly so, I am not going cover here

AEM Best Practices

Know the power of sling models

The power of sling models depends on how effectively you design your AEM component’s, If you do the proper design then you can save lot of time, actually the sling models are just POJOs, you can directly map POJO’s to resource objects to access resource values directly in the WCMUsePojo classes, to get more information on Sling models you can refer below article and  for sample code you can download AEM ToolKit

Handling Jquery libs

The common mistake which people do is including JQuery libs at component level, the disadvantage of including at component level is, for each and every component the system will make a request to server to download multiple versions of JQuery libs, sometimes it may impact on page performance and also you will see lot of undefined JavaScript errors because of loading multiple versions of JQuery libs

Mostly, this happens when there is no creative agency or FED people in your project and also when developers writes JavaScript and lack of co-ordination between them

Solution:

You need to maintain it in central location, I suggest create a separate clientlib for Jquery versions and include at Basetemplate level, if new version comes just update client libs or add this as dependencies to other clientlibs

In some scenarios, the system will force you to include at a component level, in such cases use JQuery.noConflict () option to avoid conflicts

Consider that the AEM also loads Jquery libs which are unavoidable, most of the authoring functionalities works on “cq.jquery”  so, while writing custom script bases on new jquery version it is good to use JQuery.noConflict () and also change the references to some new variable something like $JQ or $KQ etc…,  the AEM authoring functionalities uses  “$” and  $CQ, so it is better to avoid these

Another important thing is don’t put entire CSS and js in a single file, try to create component specific CSS and js files and call out in js.txt or css.txt file to have better maintenance and to save debugging time while you are in M&O

Deploy CSS or JS files into production

Is it right approach deploying CSS or JavaScript files as part of deployment package in “Content Management System”? for some projects it is “YES” and for some projects it is “NO” and it totally depends on requirement but, I suggest you create a separate project for only front-end related stuff, the advantage you will get is you will have an option to deploy code and content packages separately, I mean whenever it is required

I have seen some people who came from traditional web development and no knowledge on CMS trying to deploy CSS and JS files through package manager and finally mess up entire environment like overriding existing CSS and JS files which were added by front end people

If you see that in any CMS you can find two types of content, static and  dynamic content

Dynamic content:

The content which you think it changes very frequently by content author’s or front end people need to be handled by using a separate project, the purpose of this is to check-in only front end related files which are totally different from your actual code package, whenever any CSS or JS files changes, you do not  need to deploy your code package, you can just build and deploy your front end project

Ex: Style sheets, Js files etc…

Static content:

The content which you think it will not change in future need to be deployed as part of code package such as your code, global style sheets, images, JavaScript files etc…

Handling i18n strings

Usually we create i18n folder at the component level but, when it comes to maintenance sometimes it gives you problems, suppose in future if you want to create new locale it is very difficult to check entire solution to identify i18n folders, which needs to convert into new locale and which may lead to maintenance issue and moreover there is a chance of having duplicate entries

These duplicate entries may override existing ones and you need to spend lot of time to debug the issue

You can consider other option which is creating i18n folder at /apps level, if the client is planning to use human translators to convert to another locale then we can save some amount to the client by reusing content  because the translator’s charges certain amount for every word they convert and also we can avoid duplication of entries

Avoid loading unnecessary jars

Try to avoid loading unnecessary jar files through POM entries, identify all required common jar files and create separate parent module ( pom.xml file ) and import that into other modules

If you are working on large project then it is best to have central repository to manage all your dependencies, something like Apache Archiva, because you will have full control on dependencies

Try to leverage OOTB components

Once you receive requirements from your client the first thing which you need to do is check whether it is feasible with OOTB functionality or not, if it feasible then try to re-use OOTB things, if it is not then only start developing custom components

Minify CSS and JS

Using HTML Library Manager service, we can enable or disable CSS and js minification for entire application but, before implementing this make sure that the front end team should not do the minification using front-end technologies, we have seen some JS issues when we applied both ways

I suggest you choose either of one, minification from front-end side or AEM HTML Library Manager service in order to avoid js issues because there is no point of applying minification on top of minified library

Don’t use administrative session

Don’t use Admin Session to access the ResourceResolver, it is deprecated and also from a security point of view it is not recommended, with this you are granting full permissions, so I suggest you use impersonation approach which is available in SharePont, In AEM this feature is added AEM 6+, the advantage we get is you will have the flexibility to apply for specific permissions only for particular Service User

In AEM this feature is added AEM 6+ onwards, the advantage we get is we can apply for permissions only for particular Service User, The Service User will not have full permissions and he/she will have whatever permissions applied using useradmin dashboard

You should know when to close session object

If you are explicitly opening session with admin or service account, then you are responsible for closing the session object explicitly, otherwise, you will have a session leakage and you may run out of resources, the session which you are not created by you should not close and it will be handled by sling

If you are planning to run sonar, then it is good to use AEM plugin to find out session leakage

Use fragments

If you have requirement to author content only once and re-use in multiple places then I would recommend you to use either paragraph reference or experience fragments with this you can author content only once in configuration page and render it on other places, you can use experience fragments for drag and drop functionalities or if you want to load through authoring dialog fields then use paragraph reference

All environments should be in sink to avoid surprises

Always make sure that the environments should be in sink to avoid last minute surprises and also to save debugging time, I strongly recommend don’t directly work on production environment, first fix it in lower environments, then test it in production environment

Usually, this happens in maintenance projects when there is no time some people do the quick fix in the production environment, if you want to deploy quick fix in prod I recommend you define a process first then build a separate hotfix package and deploy it, if you directly work on prod environment it is difficult to roll back if something goes wrong

Resourceresolver.map

If you are using link rewriter then you need to use resourceresolver.map to rewrite images and URL’s which are in scripts, the OOTB link rewriter does not support rewriting scripts and image URL’s

Another approach is if you have some business logic on URL’s such as trimming, shortening etc… then, you can use transformation factory to rewrite all links

Use Externalizer

Try to use externalizer service if you are planning to build public facing absolute URL’s, reading domain name from the page properties and build it using string concatenations is not a good practice, it may give some problems, the first thing is when it comes security, you are giving control to author to change  domain name which is not recommended

The externalizer service helps you to manage external URL’s at central locations at system/console level, so whenever something changes you can quickly change it and also you can configure separate URL’s for author and publish environment and call externalizer.publishLink to get the publish URL

Servlets

The Adobe recommendation is to use resource based servlets instead of path based one’s, the resource based servlets are access controlled and also the selectors works only when you use resourceTyps based servlets so, try to create resource-based servlets instead of path based one’s

OSGI Annotations

Use OSGI annotations instead of Felix based one’s this works only AEM 6.2 onwards, for more information refer this article OSGI annotations