Expand my Community achievements bar.

SOLVED

Caching pages based on the values of a cookie

Avatar

Level 2

I am building an application where the content of the page will differ based on a user cookie that specifies details of a subscription level.

 

the components read the cookie and can change what they display based on it, however I still want to implement some caching on the site at the dispatcher to improve performance.

 

Is there a way in the dispatcher cache of caching variations of the content based on the value of a cookie, or a header?

1 Accepted Solution

Avatar

Correct answer by
Level 9

Hi @taggatmerkle,

 

This solution is compatible with AEMaaCS. Of course, on AEMaaCS we have CDN before Apache/Dispatcher, that's why CDN will get static page instead of dynamic.

To solve this I see 2 options:

1) Use JavaScript Include. Read here: https://sling.apache.org/documentation/bundles/dynamic-includes.html#javascript-include 

2) Disable CDN cache for some HTML pages where you have dynamic components.

 

I'd not suggest option #2, because of potential performance problems.

 

Best regards,

Kostiantyn Diachenko.

View solution in original post

14 Replies

Avatar

Level 9

Hi @taggatmerkle ,

 

There is an official documentation for Caching Secured Content: https://experienceleague.adobe.com/en/docs/experience-manager-dispatcher/using/configuring/permissio.... Take a look into it.

 

In addition, I would suggest to integrate Sling Dynamic Include just for your component. It might allow you to cache whole page except some components content that have to be dynamically rendered. 

 

Best regards,

Kostiantyn Diachenko.

Thanks, this still only caches 1 copy of the page and we want a page per user group (by cookie)

Avatar

Community Advisor

@taggatmerkle 
Is your whole page changes for a specific user group or certain components on the page changes the content of it based on Cookie/User Group condition?

 

Avatar

Level 2

It is only certain components.

We have some containers that will only show if the user is in the right group, and some components will change the details they show based on the groups.

Avatar

Community Advisor

Avatar

Community Advisor

Hi @taggatmerkle 

If you are using CDN, CDN can request two different pages from origin, based on selector(append selector based on cookie or value).

But you won't be able to achieve any kind of browser cache if you are going to generate dynamic content from server side.



Arun Patidar

Avatar

Level 2

The page in AEM is the same, we have components that render differently based on the values in the encrypted cookie, and hence want to be able to cache them for each of the "user types"

 

We do have some pieces of content that will be visible only to certain user types.

Hi @taggatmerkle ,

 

So, here is a summary of all solutions:

1) Introduce Sling Dynamic Include for caching components for different users. You need to create configurations per component or per group of components. See more: https://experienceleague.adobe.com/en/docs/experience-manager-learn/foundation/development/set-up-sl...

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0"
    xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
    jcr:primaryType="sling:OsgiConfig"
    include-filter.config.enabled="{Boolean}true"
    include-filter.config.path="/content"
    include-filter.config.resource-types="[my-app/components/content/highly-dynamic]"
    include-filter.config.include-type="SSI"
    include-filter.config.add_comment="{Boolean}false"
    include-filter.config.selector="subscription-include"
    include-filter.config.ttl=""
    include-filter.config.required_header="Server-Agent=Communique-Dispatcher"
    include-filter.config.ignoreUrlParams="[]"
    include-filter.config.rewrite="{Boolean}true"
/>

2) Add rewrite rule on apache server to append unique identifier as selector to SDI paths.

# Check if the "subscription" cookie is set
RewriteCond %{HTTP_COOKIE} subscription=([^;]+) [NC]
# Match URLs ending with ".subscription-include.html"
RewriteRule ^(.*)\.subscription-include\.html$ $1.subscription-include.%1.html [L]

3) Verify that rewritten paths are cached. Check dispatcher.any. Actually, you should allow "*.html", but below you can find more customized rule:

/rules {
  ...
  /0009 {
    /glob "*.subscription-include.*.html*"
    /type "allow"
  }
}

 4) On AEM back-end you can build you logic either by selector or by cookie. I would suggest to implement Sling Filter that will parse selectors of the path and in case of subscription selectors set request attributes.

@Component(
        service = Filter.class,
        property = {
                EngineConstants.SLING_FILTER_SCOPE + "=" + EngineConstants.FILTER_SCOPE_REQUEST,
                EngineConstants.SLING_FILTER_PATTERN + "=/content/.*"
        }
)
public class SubscriptionFilter implements Filter {

    private static final Pattern SUBSCRIPTION_PATTERN = Pattern.compile("subscription-include\\.(\\w+)");

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain filterChain)
            throws IOException, ServletException {
        SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request;
        String selectorsString = slingRequest.getRequestPathInfo().getSelectorString();
        if (selectors == null) {
            filterChain.doFilter(request, response);
            return;
        }        

        Matcher matcher = SUBSCRIPTION_PATTERN.matcher(selectorsString);
        if (matcher.matches()) {
            String subscription = matcher.group(1);
            if (StringUtils.isNotBlank(subscription)) {
                request.setAttribute("subscription", subscription);
            }
        }
        
        chain.doFilter(request, response);
    }
}

 

Best regards,

Kostiantyn Diachenko.

Thanks, I am looking how to implement this on aemaacs

Avatar

Correct answer by
Level 9

Hi @taggatmerkle,

 

This solution is compatible with AEMaaCS. Of course, on AEMaaCS we have CDN before Apache/Dispatcher, that's why CDN will get static page instead of dynamic.

To solve this I see 2 options:

1) Use JavaScript Include. Read here: https://sling.apache.org/documentation/bundles/dynamic-includes.html#javascript-include 

2) Disable CDN cache for some HTML pages where you have dynamic components.

 

I'd not suggest option #2, because of potential performance problems.

 

Best regards,

Kostiantyn Diachenko.

I am attempting to implement this solution, but I am going for option 3 which is to have the CDN doing cookie based caching which will resolve the issue of caching while still allowing cookie based data to be presented.

Avatar

Level 7

To cache variations of a page based on a user cookie in AEM:

1. Use Sling Dynamic Includes: Cache the static parts of the page while dynamically rendering user-specific components based on cookies (e.g., subscription level).
2. Use URL Selectors: Configure the dispatcher to cache pages with different URLs for each user group (e.g., /page.html;userType=premium).
3. Configure Dispatcher: Ensure the dispatcher is set up to cache based on cookies or URL selectors, so different user types get different cached versions.

Avatar

Level 4

Hi @taggatmerkle 

Dispatcher doesn't provide such functionality to maintain a separate cache on the basis of cookies.

Please check AEM Sling dynamic include. You can bypass specific components to bypass the cache within the page and that will render the content on the basis of the business logic you have written for the cookie specific user data.

check this to integrate it in project: https://experienceleague.adobe.com/en/docs/experience-manager-learn/foundation/development/set-up-sl...

Avatar

Level 2

Just a note, this is on AEMaaCS and adobe sling dynamic includes is not supported on AEMaaCS