I would like to use a custom page for some HTTP error, so I use the .htaccess file. At the same time I would like to use the URL rewriting, but that doesn't work and I don't know why.
This is my .htaccess :
#Rewrite options
RewriteEngine On # Turn on the rewriting engine
#Error
RewriteRule ^error/([0-9]{3})/?$ index.php?page=error-$1 [NC,L]
#Other options
ErrorDocument 403 error/403
ErrorDocument 404 error/404
<Files .htaccess>
order allow,deny
deny from all
</Files>
IndexIgnore *
Options All -Indexes
The argument of the ErrorDocument directive can be a string, an internal URI or an external URI. The "error/404" variant you have here is interpreted as a string, so Apache just outputs it as though it was a hard-coded error message. This isn't what we want now.
Now, if we prepend it with a slash, "/error/404" will be a local redirect, but local relative to the DocumentRoot. So if we have the .htaccess file at http://example.com/testit/.htaccess, and we request http://example.com/testit/something.txt, the document http://example.com/error/404 will be loaded. To avoid this, simply prepend it with the path of the subdirectory ( /testit/error/404 ), or otherwise play around with DocumentRoot. However, please be aware that it's already a soft redirect: the browser's address bar will show the URI the user entered, so there's no need to make the ErrorDocument's URI pretty. Just
ErrorDocument 404 /path-to-my-folder/index.php?page=error-404
will give a perfectly good behaviour: when we request, say, example.com/something.txt which is not found, the address bar will continue to show example.com/something.txt, while the content of index.php?page=error-404 will be served.
But if you really want to display /error/404 in the browser's address bar, give the ErrorDocument an absolute URI as an argument, like ErrorDocument 404 http://my-server/my-path/error/404
This will force the browser to do a hard-redirect to that document; the request will be captured by the mod_rewrite rule, and the content of index.php?page=error-404 will be served, while the address bar will continue to show /error/404. The downside of this method is that you will have to manually set the 404 response header, and you'll have no idea what the original request was. It may also confuse robots, and will also confuse visitors, as it's not the behaviour they expect.
My advice is, just make it a relative link, like this:
#Rewrite options
RewriteEngine On # Turn on the rewriting engine
#Other options
ErrorDocument 403 /path-to-my-subfolder/index.php?page=error-403
ErrorDocument 404 /path-to-my-subfolder/index.php?page=error-404
IndexIgnore *
Options All -Indexes