Expand my Community achievements bar.

Submissions are now open for the 2026 Adobe Experience Maker Awards.
SOLVED

Custom Clientlib cq.authoring.editor.sites.page raise condition when using javascript functions within cq:editConfig --> cq:listener

Avatar

Level 2

Hi all,

For a client we required some custom javascript to be executed when components are inserted, edited and deleted

For this we created our own clientlib and assigned it the following category:

cq.authoring.editor.sites.page


Full .content.xml file

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
allowProxy="{Boolean}true"
categories="[cq.authoring.editor.sites.page]"/>



This clientlib contains a JS file which has some neat functions i pass along to the cq:listeners in the cq:editConfig file of various components.

Here is a short version of the JS file:

(function(window, Granite) {
"use strict";

const myClient = window.myClient || {};
const authoringActions =myClient.authoringActions || {};
window.myClient = myClient;
myClient.authoringActions = authoringActions;

const privateFunctions = {};

authoringActions.openEditDialog = function() {
etc....
};

authoringActions.refreshContentFrame = function() {
etc..
};

etc...

}(window, Granite));


Here is an example how we use it within a cq:editConfig of a component


<?xml version="1.0" encoding="UTF-8"?>
<jcr:root
xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:EditConfig"
cq:actions="[INSERT,EDIT,DELETE,COPYMOVE,PASTE]">
<cq:listeners
jcr:primaryType="cq:EditListenersConfig"
afteredit="myClient.authoringActions.refreshContentFrame"
afterinsert="myClient.authoringActions.openEditDialogRefreshOnSaveDeleteOnCancel"
afterdelete="myClient.authoringActions.refreshContentFrame"/>
</jcr:root>


This is the problem:

approximately 7 out of 10 times, when loading in the authoring environment the author is greeted with the message:

"An error occurred, please check the browser console for more details."

When checking the console we can read this:

Handler of component is invalid -> ReferenceError: myClient is not defined
    at eval (eval at ns.util.sanitizeCQHandler etc....


As this occurs are random this tells me that this is a raise condition
It is probably caused by AEM checking if the validity of the configured cq:listeners to see if the javascript that needs to be executed actually exists.

During this check, the clientlib apparently was not initialised yet.
Funny thing is, when the author start authoring, all javascript functionality assigned to the listeners work just fine even if the error was given prior.


The ideal solution is to find a way to have the Javascript from this clientlib fully initialised prior the sanitizeCQHandler did it's thing (perhaps we can change to another category?)

But i don't mind turning sanitizeCQHandler off (if possible) for these components as a fallback

Did you experienced this aswell? If so, how did you work around it?

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @DennisAtDept ,

Yes switching the category from cq.authoring.editor.sites.page to cq.authoring.editor is a valid and recommended fix for the race condition you're experiencing. And since your clientlib only contains utility functions for cq:listeners, the side effects are minimal but it’s important to be aware of the trade-offs:

View solution in original post

4 Replies

Avatar

Level 2

Switching the category from 

cq.authoring.editor.sites.page

to

cq.authoring.editor

seems to have solve this issue. Any potential problems when doing this?
The clientlib will only contain functions to be called by the cq:listeners.

Avatar

Correct answer by
Community Advisor

Hi @DennisAtDept ,

Yes switching the category from cq.authoring.editor.sites.page to cq.authoring.editor is a valid and recommended fix for the race condition you're experiencing. And since your clientlib only contains utility functions for cq:listeners, the side effects are minimal but it’s important to be aware of the trade-offs:

Avatar

Community Advisor

Hi @DennisAtDept,

I think you are right - here is why:

The cq.authoring.editor category loads much earlier than cq.authoring.editor.sites.page, which is page-specific and deferred until after the editor chrome and page frame are bootstrapped. This ensures your global object (window.myClient) is defined before AEM tries to resolve listener handlers like afteredit.

So yes - switching the category to cq.authoring.editor prevents the race condition by guaranteeing earlier execution of your clientlib.

Now coming back to your question - Any downsides to using cq.authoring.editor?
  1. Global loading:
    This category loads on all pages in the editor (eg. sites, experience fragments, templates, etc.). If your JS is only needed for sites pages, this could be a mild performance overhead.

  2. Editor performance:
    If your custom code grows large or includes 3rd-party libraries, loading it early and globally might slow down AEM authoring UI initialization.

  3. Potential collisions:
    Since cq.authoring.editor is shared among other libs, avoid defining broad globals or anything that could interfere with AEM’s native code.


Santosh Sai

AEM BlogsLinkedIn


Avatar

Level 2

Hi all,

Thank you all for your feedback.

All warnings are fair and are taken into consideration.

Indeed, to isolate the functionalities, we opted in to just use the clients name as the name of the main object all of our custom code will be assigned to. This should not clash with  AEM OOTB  functionalities in anyway. These functions are going to be used by most components if they need them and are not specifically created for single component or template.

The functions we create are very small and only really use available functionality within the Granite.author object with the exception to reload the ContentFrame. 
While testing we did not notice any drawbacks and all seems to be working as intended.