Published on

AEM Dispatcher Series 6 - Handling Vanity URLs, Sessions, and `/renders`

Authors

If you’ve followed this series so far, you already know how Dispatcher caches and secures your site.
But what happens before content is cached — when Dispatcher decides which Publish instance to talk to?
Or what about after caching — when users log in, and caching must behave differently?

And then there’s another common topic developers often encounter — vanity URLs those clean, short links like /offers or /contact that map to long AEM paths.

In this post, we’ll explore how the Dispatcher handles these three critical components:

  • /renders: how it connects to AEM Publish instances
  • /sessionmanagement: how it handles logged-in users
  • how to properly handle vanity URLs using Dispatcher and Apache

1. Understanding /renders: Connecting Dispatcher to AEM Publish Instances

One of the most fundamental sections in dispatcher.any is /renders.

If you imagine Dispatcher as the front-of-house of a restaurant, the /renders are like the kitchen staff, the actual AEM Publish servers that prepare the requested content.

Whenever Dispatcher doesn’t find a cached version of a page, it fetches it from one of the Publish instances defined under /renders.

Example: /renders Configuration

/renders {
  /publish1 {
    /hostname "publish1.mycompany.com"
    /port "4503"
  }
  /publish2 {
    /hostname "publish2.mycompany.com"
    /port "4503"
  }
}

Here’s what this configuration does:

  • Defines two Publish instances for load balancing.
  • If one instance is unavailable, Dispatcher automatically switches to the next.
  • You can define multiple renders for redundancy and scalability.

Developer Tip: When to Check /renders

If your requests are timing out or returning 502 or 503 errors, check the following:

  • The Publish instance is reachable from the Dispatcher host.
  • The hostname and port match what’s configured in AEM Publish under Apache Felix Jetty HTTP Service(/system/console/configMgr)
  • Your network or firewall allows communication between Dispatcher and Publish.

You can test connectivity directly using:

curl -I http://publish1.mycompany.com:4503/content/mysite.html

If this fails, Dispatcher cannot fetch uncached content — which means users will see errors until the cached entries expire.

Sticky Connections with /stickyConnectionsFor

If your site includes personalized content or form-based flows, you might need sticky connections.

/stickyConnectionsFor "/path/to/secured/content"

This ensures that all requests from a particular session go to the same Publish instance — maintaining consistency for logged-in users or form submissions.

2. Handling Logged-In Users: /sessionmanagement

Most AEM sites are public, but many include logged-in areas such as portals, dashboards, or account sections.
In these cases, Dispatcher must know how to manage sessions, since caching authenticated pages publicly would be a serious security issue.

This is controlled through the /sessionmanagement section.

Example: Basic /sessionmanagement

/sessionmanagement {
  /directory "/opt/dispatcher/sessions"
  /encode "md5"
  /header "Cookie:login-token"
  /timeout "300"
}

Property

Description

/directory

Directory where Dispatcher stores session-related data.

/encode

Defines how session IDs are encoded (commonly md5).

/header

Specifies the HTTP header that identifies the session (often Cookie:login-token).

/timeout

Duration in seconds before the session expires.

This setup ensures that Dispatcher doesn’t mix responses between different authenticated users.
Each logged-in session effectively creates its own temporary cache area.

Developer Tip: Don’t Cache Authenticated Responses

Even when session management is enabled, always disable caching for private or personalized areas.

/cache {
  /rules {
    /0000 { /glob "*.html" /type "allow" }
    /0001 { /glob "/content/secure/*" /type "deny" }
  }
}

This ensures private data is never cached and shared across users.

3. Handling Vanity URLs with Dispatcher and mod_rewrite

Vanity URLs are short, readable paths like: https://www.mysite.com/contact

instead of:https://www.mysite.com/content/mysite/en/contact-us.html

In AEM, authors can set vanity URLs under Page Properties → Vanity URL.
However, Dispatcher doesn’t automatically know how to resolve them — so we typically handle vanity mapping at the Apache layer, using rewrite rules.

How Vanity URLs Work in AEM

  1. Authors define vanity paths (e.g., /offers) for pages.
  2. These paths are stored in the AEM repository.
  3. The Vanity URL Servlet on Publish maps them to their actual page paths.

However, for Dispatcher to serve these efficiently, we configure the mapping in Apache before the request reaches Dispatcher.

Example: Vanity URL Handling in Apache

Add rewrite rules in your Apache configuration (before the Dispatcher module is loaded):

RewriteEngine On

# Redirect vanity URLs to actual paths
RewriteRule ^/offers$ /content/mysite/en/offers.html [PT,L]
RewriteRule ^/contact$ /content/mysite/en/contact.html [PT,L]

Here’s what happens:

  • A user requests /offers.
  • Apache rewrites the URL to /content/mysite/en/offers.html.
  • Dispatcher serves the cached content if available; otherwise, it fetches it from Publish.

The [PT] flag passes the rewritten URL through to the next handler (Dispatcher).

Testing Vanity Rewrites

You can test if rewrite rules are working properly using:

curl -I -L http://localhost/offers

If you receive a 200 OK response with the correct content, your rewrite rule is correct.
If you see 404 or 403, verify your /filter section — Dispatcher might be blocking the rewritten path.

4. Putting It All Together

Here’s an example that combines /renders, /sessionmanagement, and caching rules in a single dispatcher.any configuration:

/farms {
  /mysite {
    /virtualhosts { "*.mysite.com" }

    /renders {
      /publish1 { /hostname "publish1" /port "4503" }
      /publish2 { /hostname "publish2" /port "4503" }
    }

    /filter {
      /0000 { /type "allow" /url "/content/mysite/*" }
      /0001 { /type "deny" /url "/system/*" }
    }

    /cache {
      /docroot "/opt/dispatcher/cache"
      /rules {
        /0000 { /glob "*.html" /type "allow" }
        /0001 { /glob "/content/secure/*" /type "deny" }
      }
    }

    /sessionmanagement {
      /directory "/opt/dispatcher/sessions"
      /encode "md5"
      /header "Cookie:login-token"
      /timeout "300"
    }

    /statfileslevel "3"
  }
}

This setup:

  • Defines multiple Publish instances for redundancy.
  • Disables caching for secure content.
  • Handles user sessions securely.
  • Supports vanity URLs via Apache mod_rewrite.

5. Developer Troubleshooting Checklist

| Issue                               | Check                                                               |
| ----------------------------------- | ------------------------------------------------------------------- |
| Requests timing out                 | Verify `/renders` hostnames and ports are reachable.                |
| Logged-in content being cached      | Check `/cache` rules and `/sessionmanagement`.                      |
| Vanity URLs returning 404           | Confirm rewrite rules and `/filter` paths.                          |
| Multiple login sessions conflicting | Ensure unique `/directory` and encoding settings per farm.          |


Key Takeaways

  • /renders define which Publish servers Dispatcher communicates with.

  • /sessionmanagement isolates and secures authenticated user sessions.

  • Vanity URLs require Apache rewrite configuration to work seamlessly with Dispatcher.

  • Developers should test vanity rules, session behavior, and render connectivity locally before deployment.

Next: Part 7 — AEM Dispatcher Troubleshooting: A Developer’s Debugging Playbook