Skip to main content
Level 2
August 12, 2026
Solved

cq:lastReplicationAction not usable on AEM Publish/Dispatcher - component renders empty

  • August 12, 2026
  • 4 replies
  • 87 views

Hi ,

I am working on a requirement where a custom sling model needs to exclude pages that are unpublished/hidden from navigation, while recursively walking a page tree vis listchildren(). The issue driving this: page that are hidden in nav, unpublished and have a redirect configured still showing up in the list. so we need to explicitly hide unpublished pages, not just hidden ones. 

To fix this, I check cq:lastReplicationAction/cq:lastReplicationAction_Publish  on each pages’s ValueMap to filter unpublished ones. 

Resource contentResource = childPage.getContentResource();

            if (contentResource != null) {

                ValueMap properties = contentResource.getValueMap();

                isHidden = properties.get("hideInNav", false);

                isPublished = properties.get("cq:lastReplicationAction", String.class);

                 isPublishedDispatcher = properties.get("cq:lastReplicationAction_Publish", String.class);

            }



            if (isHidden || 

                (StringUtils.isBlank(isPublished) && StringUtils.isBlank(isPublishedDispatcher)) ||

                "Deactivate".equalsIgnoreCase(isPublished) || 

                "Deactivate".equalsIgnoreCase(isPublishedDispatcher)) {

                continue;

            }

 

  • Works on author
  • Works on local AEM SDK publish 
  • On Publish through dispatcher (no way to bypass it on AEMaaCS): component renders empty.  Properties confirmed present on Author. Still empty after a full pipeline deployment. 

Questions:

  1. Does this hld the same way on AEMaaCS publish?
  2. What is the right way to check “is the page published” from a sling mode on Publish/Dispatcher? 
    Best answer by Shashi_Mulugu

    Hi ​@SiddhiDa2 ,

     

    If i understand your problem statement correctly,   You are looking at this from the wrong angle—you should not be checking replication status on a Publisher at all.

    ​Why This Approach Is Fundamentally Flawed

    ​Existence = Published: If a page JCR node exists on a Publish instance, it is already published. There is no need to query cq:lastReplicationAction to verify its state on Publish.

    ​Replication Metadata Belongs to Author: Properties like cq:lastReplicationAction, cq:lastReplicated, and cq:lastReplicatedBy are Author-centric metadata intended for the Sites Console and Page Properties on Author. They are stripped or omitted during replication to Publish by design.

     

    So write your code to check what is the run mode and if it Author check all your conditions as listed above,  but if it is Publisher dont check replication checks..

     

    Use runmode based configuration if required.

    4 replies

    Level 4
    August 12, 2026

    Hi ​@SiddhiDa2,

    The issue is that cq:lastReplicationAction_Publish is written by the publish replication agent, but only on the Author instance, Publish never writes that property to itself. So when your model runs on Publish, isPublishedDispatcher is always blank, and your condition ends up being true for every page, which is why everything gets skipped.

     

    Instead of reading these replication properties by hand, I’d just adapt to ReplicationStatus, it handles the author/publish difference for you:

    ReplicationStatus repStatus = contentResource.adaptTo(ReplicationStatus.class);
    boolean isActivated = repStatus != null && repStatus.isActivated();

    if (isHidden || !isActivated) {
        continue;
    }
     

    That replaces both your isPublished/isPublishedDispatcher checks with one line that works the same way on both instances.

     

    To your questions - no, this won’t hold the same way on Publish, since that suffixed property simply isn’t there. And for checking “is this published” from a Sling model that runs on Publish/Dispatcher, ReplicationStatus is the way to go rather than reading the raw properties.

     

    One thing to watch for once you fix this: if you’re still seeing stale/incorrect results only when going through Dispatcher (but it’s fine hitting Publish directly), that’s a caching problem, not a code problem, Dispatcher won’t re-run your model on a cache hit, so you’d need a flush rule tied to activation for that page.

    SiddhiDa2Author
    Level 2
    August 12, 2026

    Thanks for the suggestion, I tried adaptTo(ReplicationStatus.class); too, but got same result, works on author but on publish through dispatcher while component renders empty, not just individual pages. Seems like whatever it relies on isn’t reliably available on publish either. Any other suggestions?

    Level 4
    August 13, 2026

    Hi ​@SiddhiDa2,

    If the whole component goes empty on Publish (not just certain children getting filtered out), that’s a different symptom than a logic bug in your CUG/publish check, it points to the loop or the resource resolution itself failing before your filtering logic even runs. A few things to check, in order of likelihood:

    1. Anonymous permissions on Publish. Requests through Dispatcher hit Publish as the anonymous user, not as you. If anonymous doesn’t have jcr:read on the parent page(s) you’re calling listChildren() on, the whole traversal can silently return nothing, no exception surfaces, it just looks empty. Worth testing directly against Publish (bypassing Dispatcher) with a fresh incognito/anonymous session to rule this out from your actual browser test.
    2. Swallowed exception. If adaptTo(ReplicationStatus.class) or listChildren() throws for any reason on Publish (permissions, null resource, etc.), and that’s inside a try/catch that logs-and-continues or fails the whole loop early, you’d see exactly this, empty component, no obvious per-page cause. Check error.log on Publish (not Author) during a request that renders empty, that’ll tell you definitively if something’s throwing.
    3. Dispatcher cache. Rule this out explicitly: hit the resource directly on Publish’s port (bypassing Dispatcher) and see if it’s still empty. If Publish direct works but Dispatcher doesn’t, you’re looking at a stale cached empty response, not a code issue, check .stat files / cache headers for that page, or just flush that path and retest.

    Start with #3 since it’s the fastest to rule out, then #1. If both check out and it’s still empty, paste what’s actually in error.log on Publish for that request,  that’ll narrow it down fast.

    Shashi_Mulugu
    Community Advisor and User Group Leader
    Shashi_MuluguCommunity Advisor and User Group LeaderAccepted solution
    Community Advisor and User Group Leader
    August 13, 2026

    Hi ​@SiddhiDa2 ,

     

    If i understand your problem statement correctly,   You are looking at this from the wrong angle—you should not be checking replication status on a Publisher at all.

    ​Why This Approach Is Fundamentally Flawed

    ​Existence = Published: If a page JCR node exists on a Publish instance, it is already published. There is no need to query cq:lastReplicationAction to verify its state on Publish.

    ​Replication Metadata Belongs to Author: Properties like cq:lastReplicationAction, cq:lastReplicated, and cq:lastReplicatedBy are Author-centric metadata intended for the Sites Console and Page Properties on Author. They are stripped or omitted during replication to Publish by design.

     

    So write your code to check what is the run mode and if it Author check all your conditions as listed above,  but if it is Publisher dont check replication checks..

     

    Use runmode based configuration if required.