Search code examples
.htaccesscodeignitermod-rewritemod-alias

Using 301 redirect (.htaccess) or a different solution to not change the url


I changed some URLs on my website, so now I need to redirect the old URLs (due to external links) to the new ones.

I tried to use something like this in my .htaccess file:

Redirect 301 /pt/oldpage https://www.example.com/pt/newpage

The redirect works (it opens the correct page), but the problem is that the URL of this page is changed to something like this:

https://www.example.com/pt/newpage?/pt/oldpage ~

Any idea of what is wrong?

My website uses the FrameWork CodeIgniter, if this is necessary.

This is my .htaccess file (With the solution!):

RewriteEngine on
RewriteRule ^pt/oldpage$ https://www.example.com/pt/newpage? [R=302,L]
### WWW & HTTPS

# ensure www.
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# ensure https
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

### WWW & HTTPS
RewriteCond $1 !^(index\.php|images|assets|recursos|support|robots\.txt|sitemap\.xml|sitemap\.html)
RewriteCond %{REQUEST_URI} !^/[0-9]+\..+\.cpaneldcv$
RewriteCond %{REQUEST_URI} !^/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
RewriteRule ^(.*)$ index.php?/$1 [L]

Redirect 301 /pt/oldpage https://www.example.com/pt/newpage
RewriteRule ^pt/oldpage$ /pt/newpage? [R=302,L]

Options -Indexes

<IfModule mod_expires.c>
  ExpiresActive on
  ExpiresByType image/jpg "access 1 month"
  ExpiresByType image/gif "access 1 month"
  ExpiresByType image/jpeg "access 1 month"
  ExpiresByType image/png "access 1 month"
  ExpiresByType text/css "access 1 month"
  ExpiresByType application/x-javascript "access plus 1 month"
  ExpiresByType text/javascript "access plus 1 month"
  ExpiresByType application/javascript "access plus 1 month"
  ExpiresByType image/x-icon "access plus 1 month"
  ExpiresByType image/icon "access plus 1 month"
  ExpiresByType application/x-ico "access plus 1 month"
  ExpiresByType application/ico "access plus 1 month"
  ExpiresByType application/pdf "access 1 month"
  ExpiresByType text/x-javascript "access 1 month"
  ExpiresByType application/x-shockwave-flash "access 1 month"
  ExpiresByType image/x-icon "access 1 year"
  ExpiresByType text/html "access 1 month"
  ExpiresDefault "access 1 month"
</IfModule>


##################################
#                                #
# Google Page speed optimizations#
#                                #
##################################

#Enable compression

<IfModule mod_deflate.c>
  # Compress HTML, CSS, JavaScript, Text, XML and fonts
  AddOutputFilterByType DEFLATE application/javascript
  AddOutputFilterByType DEFLATE application/rss+xml
  AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
  AddOutputFilterByType DEFLATE application/x-font
  AddOutputFilterByType DEFLATE application/x-font-opentype
  AddOutputFilterByType DEFLATE application/x-font-otf
  AddOutputFilterByType DEFLATE application/x-font-truetype
  AddOutputFilterByType DEFLATE application/x-font-ttf
  AddOutputFilterByType DEFLATE application/x-javascript
  AddOutputFilterByType DEFLATE application/xhtml+xml
  AddOutputFilterByType DEFLATE application/xml
  AddOutputFilterByType DEFLATE font/opentype
  AddOutputFilterByType DEFLATE font/otf
  AddOutputFilterByType DEFLATE font/ttf
  AddOutputFilterByType DEFLATE image/svg+xml
  AddOutputFilterByType DEFLATE image/x-icon
  AddOutputFilterByType DEFLATE text/css
  AddOutputFilterByType DEFLATE text/html
  AddOutputFilterByType DEFLATE text/javascript
  AddOutputFilterByType DEFLATE text/plain
  AddOutputFilterByType DEFLATE text/xml

  # Remove browser bugs (only needed for really old browsers)
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  BrowserMatch ^Mozilla/4\.0[678] no-gzip
  BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
  Header append Vary User-Agent
</IfModule>

Solution

  • Codeignitor uses mod_rewrite for it's front controller. You will need to use the same for your redirects, instead of using a mod_alias Redirect (which will execute unconditionally, resulting in some strange redirects - which I suspect is what's happening here).

    So, before the existing directives, try something like the following instead:

    RewriteRule ^pt/oldpage$ https://www.example.com/pt/newpage? [R=302,L]
    

    The trailing ? on the substitution will remove any query string from the request (if that is required).

    Change the 302 (temporary) to 301 (permanent) only when you are sure it's working OK - to avoid the browser caching erroneous redirects.

    Make sure you clear your browser cache before testing.