2

I am trying to setup a sub-directory with individual .htaccess. I want to redirect .html files to url without extensions and also add a trailing slash and redirect all non-slashed urls there.

Here's my the .htaccess:

<IfModule mod_rewrite.c>

Options -MultiViews -Indexes
RewriteEngine On
RewriteBase /test

# redirect urls without trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !index.html
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule (.*)$ %{REQUEST_URI}/ [L,R=301]

# remove .html extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*)/$ $1.html

</IfModule>

It does work but relative paths get .html added again and again until the max redirect limit. Sample paths that are affected: /css/test.css and css/test.css. /sub/css/test.css works fine.

Changing RewriteCond %{REQUEST_FILENAME} !-f to RewriteCond %{REQUEST_FILENAME}.html !-f or a similar permutation doesn't seem to have any effect at all.

I only want to redirect .html files. What am I missing here?

4
  • At a quick blush, it seems that %{REQUEST_URI} !index.html is not right. You want to use REQUEST_FILENAME. As well, it seems that RewriteRule (.)/$ $1.html* is putting the .html file extension back on. Or am I not getting what you are saying?? Cheers!!
    – closetnoc
    Commented Mar 5, 2016 at 4:14
  • I changed REQUEST_URI to REQUEST_FILENAME with no change. RewriteRule (.*)/$ $1.html seems to be the problem but it only applies to sub-directories. I dont understand why or what is the correct way of doing it.
    – DominicM
    Commented Mar 5, 2016 at 12:34
  • This .htaccess is presumably in your document root? "but it only applies to sub-directories" - that RewriteRule only applies to requests that are not directories or files. (?) How do you have /css/test.css and /sub/css/test.css - I would have thought only one of those exists (the one that "works")? Your directives only apply to files that don't physically exist. Incidentally if you did a check for _FILENAME}.html !-f then you would need to remove the ! - you are checking that the file exists, not that it deosn't exist.
    – MrWhite
    Commented Mar 5, 2016 at 14:17
  • No, the .htaccess is in the /sub directory as it should apply to the sub only. If i remove "!" from the 1st RewriteCond I get Object not found error. If i remove the line I get url like "localhost/sub/file.html/". Everything is contained within /sub directory including /sub/css, /sub/js etc... The paths that work and don't are the same only how they are referenced changes (relative vs absolute). You are right about the !.
    – DominicM
    Commented Mar 5, 2016 at 14:44

1 Answer 1

0

The issue was primarily due to the fact that the rule was not specific to .html files. This meant that all files would get redirected including .css files.

Here is a working .htaccess file:

<IfModule mod_rewrite.c>
Options -MultiViews -Indexes
RewriteEngine On
RewriteBase /sub

# redirect urls without trailing slash
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !index.html
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule (.*)$ $1/ [L,R=301]

# remap url to a .html file
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*)/$ $1.html [L]

</IfModule>

Relative paths within the html file still had to be changed to absolute paths like /sub/test.css

Non-existing URL's (no matching file) still end up with redirect loops which is not ideal.

2
  • 1
    Thanks for the feedback. "the rule was not specific to .html files" - although the updated rules still don't appear to be specific to .html files? "Non-existing URL's (no matching file) still end up with redirect loops" - you can include an additional check to make sure that the rewritten file would exist before actually rewriting. eg. RewriteCond %{DOCUMENT_ROOT}/sub/$1.html -f - the additional complexity is because your URLs end with a slash.
    – MrWhite
    Commented Mar 10, 2016 at 22:57
  • You are right, not sure why I thought I made it specific to html... Non-existing page rule worked perfectly. Thanks! Will update the answer when I get all the rules working as desired.
    – DominicM
    Commented Mar 11, 2016 at 15:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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