I am using the below code in my website and it's working.
RewriteEngine On
RewriteBase /a/b/
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)/?$ index.php?slug=$1 [QSA,L]
I am able to access my website like
https://www.example.com/a/b/testing
Now, I am getting issues with 301 redirections.
I have tried below code
Redirect 301 /oldurl /newurl
but while accessing the URL I am getting below URL
https://www.example.com/a/b/newurl?slug=oldurl
My expected output is the below URL.
https://www.example.com/a/b/newurl
You should avoid mixing Redirect
(mod_alias) and RewriteRule
(mod_rewrite) directives in the same context as you can get these unexpected conflicts. mod_rewrite is processed before mod_alias, despite the apparent order of the directives in the config and Redirect
works on the requested URL-path (not the rewritten URL-path and not the query string).
So, what is happening when requesting /oldurl
and you use Redirect 301 /oldurl /newurl
together with the existing mod_rewrite rewrite is:
index.php?slug=oldurl
Redirect
creates a redirect from /oldurl
(the originally requested URL-path) to /newurl
slug=oldurl
since mod_rewrite modified it./newurl?slug=oldurl
.(As noted above, this is regardless of the order of the directives, since they are from two different modules.)
You need to use mod_rewrite for the redirect as well and this must go before the existing rewrite (the order is important, since the directives belong to the same module). For example:
RewriteEngine On
RewriteBase /a/b/
RewriteRule ^oldurl$ /newurl [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule (.*) index.php?slug=$1 [QSA,L]
Any query string that might be present on /oldurl
is preserved. eg. /oldurl?foo=bar
is redirected to /newurl?foo=bar
(as it would do with Redirect
). If you specifically want to remove any query string then include the QSD
flag (Query String Discard) on the redirect (first) rule.
NB: I removed the trailing /?
on the regex since it is entirely redundant. Since you made the token optional and the preceding quantifier is greedy then .*
would consume the optional trailing slash anyway. If the intention was to exclude the trailing slash (if any) from the captured subpattern then you need to make the preceding quantifier non-greedy. eg. (.*?)/?$
(the start-of-string anchor is not required).
(I'm assuming your .htaccess
file is located in the document root - it looks like it is, from the erroneous redirect you were getting, although the /a/b/
prefix is slightly confusing - see below)
Aside:
I have tried below code
Redirect 301 /oldurl /newurl
but while accessing the URL I am getting below URL
https://www.example.com/a/b/newurl?slug=oldurl
I would have expected this to have resulted in /newurl?slug=oldurl
, not /a/b/newurl?slug=oldurl
?