I've an Angular applicaion in multiple languages. After the build process there exist a distribution for each language. These are put onto the server in locale directories:


Also all the assets, JavaScript files etc. are located per language in each directory. There's also a .htaccess file in each locale directory - only their last RewriteRule differs per language:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /fr/index.html [L]

Now the user is redirected based on the browser's language using PHP. So there's no .htaccess in the root folder yet.

The URLs look like:


I want to get rid of the slash of the root directory:


How can I solve this?

I tried DirectorySlash off without success. I was also thinking about having only one single .htaccess in the root that handles the local directory and requests for all languages. But I can't figure out, how to solve it.

  • How many languages do you have? Is the language code always 2-digit lowercase a-z? – MrWhite Feb 26 '20 at 14:19
  • @MrWhite Currently just the 2, but there will be 15-20 in the future. And yes the code will always consist of 2 letters lowercase a-z. – lampshade Feb 26 '20 at 14:43
  • What happens for requests to the document root? – MrWhite Feb 26 '20 at 22:31
  • The document root needs no further handling. It will redirect the user to the local-directory based on the browser langugae or the language selected and stored in the session. – lampshade Mar 2 '20 at 16:25
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /fr/index.html [L]

Aside: If you removed the RewriteBase directive and the /fr/ prefix on the RewriteRule substitution then all your .htaccess files in the locale subdirectories would be the same.

However, I would go for creating a single .htaccess file in the document root (parent directory) instead, as you suggest.

In order to remove the trailing slash from the language subdirectory you do need the DirectorySlash Off directive - in the root .htaccess file. However, you also need to manually rewrite the request to append the slash in order to "fix" the URL. (mod_dir etc. won't work correctly without the trailing slash.)

Try something like the following in the root .htacces file, instead of multiple .htaccess files in subdirectories:

# Prevent mod_dir from appending the trailing slash to directories (with a 301 redirect)
DirectorySlash Off
DirectoryIndex index.html

RewriteEngine On

# Allow mod_rewrite to match directories that do not have a trailing slash (when DirecrorySlash Off)
RewriteOptions AllowNoSlash

# Rewrite directory without trailing slash directly to the front-controller
RewriteRule ^([a-z]{2})$ $1/index.html [L]

# Front-controller to respective language controller
RewriteRule ^[a-z]{2}/index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-z]{2})/. $1/index.html [L]

Currently this does not do anything with requests for the document root, or "files" therein.

Also, any request for a language code that simply looks-like a language code is routed to that fron-controller, whether it exists or not (404). eg. /ab/contact is routed to /ab/index.html.

A request for /fr/ (with a trailing slash) - if the user should request it - is handled by mod_dir in the usual way and will naturally issue an internal subrequest for index.html (if the directory exists) - the DirectoryIndex. This could be externally redirected to remove the trailing slash, although you should already be linking to the slash-less URL and the appropriate canonical URL set - so it shouldn't be an SEO issue (unless the slashed URL is indexed/linked to in the wild).

Note that by disabling the DirectorySlash, this is then disabled for all child directories as well, unless you explicitly override this.

  • That looks very promising. Thank you so much for your help. – lampshade Mar 2 '20 at 16:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.