Customizing Link Checker in Adobe Experience Manager (AEM)
Ankur Rajput, December 4, 2024
Maintaining a seamless user experience is a cornerstone of any successful digital platform. In Adobe Experience Manager (AEM), the Link Checker is an essential feature designed to validate and manage the links across your site automatically. It helps content authors ensure that every link, internal or external, works as intended, avoiding the negative impact of broken links on usability and SEO.
While there are many resources available for configuring and using Link Checker, this blog will delve into some lesser-known but highly useful configurations. Specifically, we'll explore the Day CQ WCM Link Checker Configuration Factory, which allows us to customize the Link Checker validation markup, and the LinkCheckerExtension API, which enables us to extend the link validation logic to meet specific business requirements.
Note: This has been successfully tested on AEM 6.5.21.
Customization of Link Checker Output
AEM provides an OSGi Factory configuration, Day CQ WCM Link Checker Configuration Factory, that allows us to configure the markup for Expired, Invalid, and Predated links.
You might have noticed the invalid/expired links markup in the Edit mode and how the links get removed in the View as Published mode (when WCM mode is disabled).
This configuration is responsible for adding this invalid link markup. We can customize it to have our own HTML with different classes and views.
Known Issue: The Day CQ WCM Link Checker Configuration Factory is a factory config. Per the backend logic, the one with a WCM Mode entry matching the current request should be picked. However, the AEM backend code only considers the out-of-the-box config. New custom configs are not being used, so we need to modify the existing one to make it work.
Extending the Link Checker Validation Logic
The LinkCheckerExtension API is a powerful tool to customize how links are validated within the AEM environment, allowing us to extend and tailor Link Checker validation to our specific business requirements.
The Link Checker queries all registered LinkCheckerExtension extensions in no particular order as long as the extension returns a valid LinkValidity object. As soon as the first extension returns a different value, that value is returned. AEM provides an out-of-the-box implementation, com.day.cq.wcm.core.impl.page.PageLinkCheckerExtension, which validates the page references in the content based on its On/Off time property.
Use Case and Implementation: Consider a scenario where we need to validate page links based on the out-of-the-box On/Off time property, but all pages with the property alwaysValid = true
should be marked as valid regardless of their Off time.
-
Custom LinkCheckerExtension implementation and register it as an OSGi service.
import com.day.cq.rewriter.linkchecker.LinkCheckerExtension; import com.day.cq.rewriter.linkchecker.LinkValidity; import com.day.cq.wcm.api.Page; import org.apache.sling.api.resource.Resource; import org.osgi.service.component.annotations.Component; @Component(service = LinkCheckerExtension.class) public class CustomLinkCheckerExtension implements LinkCheckerExtension { @Override public LinkValidity getLinkValidity(Resource resource) { Page page = resource.adaptTo(Page.class); if (page == null) { // this extension will only validate page links return LinkValidity.VALID; } else { long timeUntilValid = page.timeUntilValid(); if (timeUntilValid == 0L) { return LinkValidity.VALID; } else if (timeUntilValid == Long.MIN_VALUE) { // Page doesn't have content return LinkValidity.INVALID; } else { Boolean isAlwaysValidPage = page.getProperties().get("alwaysValid", Boolean.class); if (isAlwaysValidPage != null && isAlwaysValidPage) { return LinkValidity.VALID; } return timeUntilValid < 0L ? LinkValidity.EXPIRED : LinkValidity.PREDATED; } } }
-
Disable the out-of-the-box PageLinkCheckerExtension so that it doesn’t mark our “alwaysValid=true” pages as invalid. We can do it manually via the OSGi components console (/system/console/components) or programmatically using the ACS AEM Commons OSGi Component Disabler.
At 3|SHARE, we thrive on solving complex AEM challenges and pushing the boundaries of what's possible with Adobe Experience Manager. If you have a unique use case or need assistance with any aspect of AEM or Adobe Experience Cloud, don't hesitate to reach out. Our team of experts is here to help you achieve your digital goals.
We love being part of the Adobe developer community and are always eager to share our solutions and insights. If you found this article helpful, let us know! And if you're looking for a dedicated team of architects and developers to elevate your AEM projects, get in touch with us today.
Topics: Adobe Experience Manager, Web Content Management System, Development, AEM, Tech
Ankur Rajput
Ankur Rajput is a Senior AEM Developer at 3|SHARE. He has completed 7 AEM Sites certifications including Developer, Lead Developer and Architect. What he enjoys about working at 3|SHARE is learning, growing, and working on the latest Web technologies with a diverse, global team. When he isn't working, Ankur loves reading and listening to Hindi poetry plus playing chess and badminton.