3

I want to remove / when I want to get access to the index file in a subdirectory folder. For example: www.example.com/test/dashboard/ to www.example.com/test/dashboard.

I tried this:

RewriteEngine On

# Remove "/" to "/dashboard"
RewriteCond %{REQUEST_URI} !index.php
RewriteCond %{QUERY_STRING} !^$
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule (.*) $1%1/ [L]

It will not remove the / from the subdirectory.

Can you please show me an example of how I can remove the / with .htaccess when I want to get access to my subdirectory?

MrWhite
  • 43,179
  • 8
  • 60
  • 84
chris oojer
  • 301
  • 1
  • 10

1 Answers1

3
# Remove "/" to "/dashboard"
RewriteCond %{REQUEST_URI} !index.php
RewriteCond %{QUERY_STRING} !^$
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule (.*) $1%1/ [L]

This doesn't "remove" anything. In fact, it will append a trailing slash to the end of the URL-path and query string, which seems a bit random?

However, you can't simply remove the trailing slash that occurs after a physical directory in the URL-path, since mod_dir will try to append it with a 301 redirect in order to "fix" the URL.

You can prevent mod_dir from appending the trailing slash with the DirectorySlash Off directive. However, you then need to manually append the trailing slash to the directory with an internal rewrite in order to correctly serve the "index file" (ie. the DirectoryIndex document).

I'm assuming you are linking to the directory without a trailing slash in your internal links.

Try the following instead in the root .htaccess file:

# Disable directory listings (mod_autoindex)
Options -Indexes

# Prevent mod_dir appending trailing slash to directories
DirectorySlash Off

RewriteEngine On

# Rewrite the URL to append a trailing slash to directories (internally)
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*[^/])$ $1/ [L]

A request for /dashboard (no trailing slash) that maps to a physical directory will be internally rewritten to /dashboard/, which will allow the "index file" to be served (by mod_dir also).

For security reasons, you need to ensure that directory listings (mod_autoindex) are disabled, otherwise, directory listings could potentially be generated for directories even when they contain a directory index document. See the security warning in the Apache docs under the DirectorySlash directive.

You need to ensure that your browser cache is cleared before testing since the 301 (permanent) redirect by mod_dir (to append the trailing slash) will have certainly been cached by the browser.

Remove the trailing slash (optional)

You could implement a canonical redirect to actually "remove" the trailing slash from the URL, should there be any requests from third parties (or search engines) that include the trailing slash. (It should already be removed on all your internal links, so this is not required to make your site "work", however, it could be required for SEO to avoid potential duplicate content.)

I'm assuming you don't want the trailing slash on any URL.

You should add the following "redirect" before the rewrite above, immediately after the RewriteEngine directive.

# Remove the trailing slash, should it appear on any 3rd party requests
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.+)/$ /$1 [R=301,L]

The check against the REDIRECT_STATUS environment variable is to ensure we do not redirect the already written request (that appends the trailing slash) by the later rewrite, during the second pass of the rewrite engine. Alternatively, you could use the END flag (Apache 2.4) on the later rewrite.


UPDATE:

.htaccess file not in the root directory

The above assumes the .htaccess file is located in the document root (and therefore applies to all directories and subdirectories thereof). If, however, the .htaccess file is in a subdirectory then you will need to modify the external redirect (that "removes" the trailing slash), since the RewriteRule pattern matches the URL-path relative to the directory that contains the .htaccess file, not the root directory.

So, if the .htaccess file is located in a subdirectory then use the following "redirect" instead:

# Remove the trailing slash, should it appear on any 3rd party requests
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/(.+)/$
RewriteRule /$ /%1 [R=301,L]

This requires an additional condition (RewriteCond directive) to capture the relevant part of the URL-path from the REQUEST_URI server variable (that contains the full root-relative URL-path), instead of the RewriteRule pattern, which will omit the parent directory(s). The %1 backreference (as opposed to $1) references the captured subpattern from the preceding condition (RewriteCond directive), as opposed to the RewriteRule pattern.

Incidentally, this will also work if the .htaccess file is in the document root.

Note that this is unable to "remove" the trailing slash from the subdirectory (that contains the .htaccess file) itself. For that you would need to make use of the .htaccess file in the parent directory (ie. document root).

Summary

The complete .htaccess would then become:

# Disable directory listings (mod_autoindex)
Options -Indexes

# Prevent mod_dir appending trailing slash to directories
DirectorySlash Off

RewriteEngine On

# Remove the trailing slash, should it appear on any 3rd party requests
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_URI} ^/(.+)/$
RewriteRule /$ /%1 [R=301,L]

# Rewrite the URL to append a trailing slash to directories (internally)
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule (.*[^/])$ $1/ [L]

Note there is no RewriteBase directive here.

MrWhite
  • 43,179
  • 8
  • 60
  • 84
  • thank you for this, but when i try it out i am getting this `Forbidden You don't have permission to access this resource. Additionally, a 403 Forbidden error was encountered while trying to use an ErrorDocument to handle the request.`. Do you know why?? – chris oojer Feb 22 '22 at 01:49
  • @chrisoojer A 403 would imply there is no "index file" (ie. `DirectoryIndex` document) in that directory? What is the name of the file in the directory you are wanting to serve? – MrWhite Feb 22 '22 at 08:58
  • @chrisoojer What other directives do you have in your `.htaccess` file (what is your custom `ErrorDocument` set to)? Please update your question with your complete `.htaccess` file. – MrWhite Feb 24 '22 at 12:05
  • Thanks! How to include subdirectories? When I try the ending slash in a subdir it redirect to url domain root – Extrange planet Jun 23 '23 at 14:17
  • 1
    @Extrangeplanet The above would already include subdirectories, providing the `.htaccess` file is located in the document root. Otherwise, you likely have a conflict with your existing directives. (But as noted above, you should already be linking to the URL _without_ a trailing slash in your internal links, so there should be no redirect under "normal" conditions.) – MrWhite Jun 23 '23 at 16:01
  • 1
    @Extrangeplanet If the `.htaccess` file is in a subdirectory then you would need to update the external redirect rule to make use of the `REQUEST_URI` server variable instead. I've updated my answer. – MrWhite Jun 23 '23 at 17:02
  • 1
    @MrWhite Thanks hermano! It works for root too :) – Extrange planet Jun 23 '23 at 17:42