Hey everyone,
I am trying to clean up the URLs in site by removing the .html extension - basically, I want /content/mysite/about.html to just be /content/mysite/about.
I have seen a few things mentioned like using Apache rewrite rules, or sling mappings under /etc/map, and even some custom ResourceResolver configs. But honestly, it’s a bit confusing figuring out what is the right way - especially when it comes to making sure it works across author, publish, and dispatcher. What is the best approach for extensionless URLs that works reliably across environments?
Solved! Go to Solution.
Views
Replies
Total Likes
Hi @AryaBa1,
Here's what usually works well in real-world setups:
In Author and Publish, configure the OSGi service:
Apache Sling Resource Resolver Factory (org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl)
Make sure these values are set:
resource.resolver.mapping=["/content/mysite/", "/"]
resource.resolver.enable.extensionless.paths=true
This makes sure AEM can resolve URLs like /about to /about.html internally without needing to see the extension.
On the Dispatcher side, use Apache rewrite rules to serve .html content when an extensionless URL is requested:
# Rewrite extensionless URLs to .html (if not requesting a file)
RewriteCond %{REQUEST_URI} !\.[a-zA-Z0-9]+$
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*)$ $1.html [PT,L]
This lets users access /about, and Apache will internally rewrite it to /about.html without changing the URL in the browser.
This is often the tricky part.
Keep using .html in links (/about.html)
Apache rewrites them so users see /about
Simple, works well with clientlibs
Use a custom HTL helper or Sling Rewrite Transformer to strip .html from generated links
Riskier unless you're confident in custom link management (especially with clientlibs, language copies, etc.)
Most of us go with Option A to avoid breaking paths.
If you're doing domain-to-path mapping (eg. map https://mysite.com
to /content/mysite), then add /etc/map.publish/https nodes like:
/etc/map.publish/https/mysite.com → /content/mysite
On AEMaaCS, use URL Mapping Rules instead, since /etc/map is restricted.
References:
Hi @AryaBa1,
Here's what usually works well in real-world setups:
In Author and Publish, configure the OSGi service:
Apache Sling Resource Resolver Factory (org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl)
Make sure these values are set:
resource.resolver.mapping=["/content/mysite/", "/"]
resource.resolver.enable.extensionless.paths=true
This makes sure AEM can resolve URLs like /about to /about.html internally without needing to see the extension.
On the Dispatcher side, use Apache rewrite rules to serve .html content when an extensionless URL is requested:
# Rewrite extensionless URLs to .html (if not requesting a file)
RewriteCond %{REQUEST_URI} !\.[a-zA-Z0-9]+$
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*)$ $1.html [PT,L]
This lets users access /about, and Apache will internally rewrite it to /about.html without changing the URL in the browser.
This is often the tricky part.
Keep using .html in links (/about.html)
Apache rewrites them so users see /about
Simple, works well with clientlibs
Use a custom HTL helper or Sling Rewrite Transformer to strip .html from generated links
Riskier unless you're confident in custom link management (especially with clientlibs, language copies, etc.)
Most of us go with Option A to avoid breaking paths.
If you're doing domain-to-path mapping (eg. map https://mysite.com
to /content/mysite), then add /etc/map.publish/https nodes like:
/etc/map.publish/https/mysite.com → /content/mysite
On AEMaaCS, use URL Mapping Rules instead, since /etc/map is restricted.
References:
Views
Likes
Replies
Views
Likes
Replies
Views
Likes
Replies