Reputation: 2640
I am trying to set up my site without file extensions in the URLs.
All my pages are php.
All my menu links have extensions removed, such as...
<a href="page1">page 1</a>
<a href="page2">page 2</a>
<a href="page3">page 3</a>
And these links all work fine.
But I am trying to now set up a .htaccess file to make 301 redirects from other external links, such as Google.
In my htaccess file, I have...
Redirect 301 /page1.php https://www.mysite.co.uk/page1
But this makes the link from Google hit the 404 page not found - it doesn't go to the page that it should.
What am I doing wrong, and how can I get these 301 redirects to work properly?
EDIT
In an effort to try and debug this, I have changed my htaccess file. My full htaccess code is now this...
DirectoryIndex index.php
CheckSpelling Off
FileETag none
ServerSignature Off
Options +FollowSymlinks
Redirect 301 https://www.mysite.co.uk/page1.php https://www.mysite.co.uk/page1
Redirect 301 https://mysite.co.uk/page1.php https://www.mysite.co.uk/page1
Redirect 301 http://www.mysite.co.uk/page1.php https://www.mysite.co.uk/page1
Redirect 301 http://mysite.co.uk/page1.php https://www.mysite.co.uk/page1
Redirect 301 www.mysite.co.uk/page1.php https://www.mysite.co.uk/page1
Now if I follow the menu link, I get to...
https://www.mysite.co.uk/page1
If I enter https://www.mysite.co.uk/page1 into the address bar of the browser, it loads the page correctly.
BUT if I follow the link from google, it ends up at...
http://www.mysite.co.uk/page1.php
How can this be?!
I have covered all possible URLs in my htaccess file, so how does this google link go to the http:// file with the .php at the end?
Upvotes: 1
Views: 2587
Reputation: 1201
I assume you are currently using Apache's MultiViews
(part of mod_negotiation) to map URLs without the file extension (eg. /page1
) to the corresponding URL with the file extension (eg. /page1.php
) - since you have nothing else in your .htaccess
file that does this.
MultiViews maps file extensions using internal subrequests, so you will need to use mod_rewrite (RewriteRule
), as opposed to mod_alias (Redirect
) in order to redirect to the extensionless URLs, since you only want to redirect direct requests, not subrequests, and it's not possible to differentiate with Redirect
.
Redirect 301 https://www.mysite.co.uk/page1.php https://www.mysite.co.uk/page1 Redirect 301 https://mysite.co.uk/page1.php https://www.mysite.co.uk/page1 Redirect 301 http://www.mysite.co.uk/page1.php https://www.mysite.co.uk/page1 Redirect 301 http://mysite.co.uk/page1.php https://www.mysite.co.uk/page1 Redirect 301 www.mysite.co.uk/page1.php https://www.mysite.co.uk/page1
You need to change the above Redirect
directives to something like the following. (Incidentally, the above directives aren't actually doing anything since the URL-path stated, eg. https://www.mysite.co.uk/page1.php
, would never match - this must be a root-relative URL-path.)
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)\.php$ https://www.example.com/$1 [R=302,L]
The RewriteCond
directive that checks against the REDIRECT_STATUS
environment variable ensures we are only redirecting initial/direct requests.
Note that this is currently a temporary (302) redirect. Change it to a 301
(permanent) redirect only after you have confirmed that it's all working OK. (301s are cached hard by the browser, so can make testing problematic.)
You could also try the following one-liner instead (without a RewriteCond
directive):
RewriteRule ^(.*)\.php$ https://www.example.com/$1 [NS,R=302,L]
Note the addition of the NS
(nosubreq
) flag, that prevents the directive being processed for internal subrequests.
UPDATE: Try disabling MultiViews
and doing this all with mod_rewrite instead (which is probably recommended). For example:
Options +FollowSymLinks -MultiViews
RewriteEngine On
# Remove .php file extension with an external redirect
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)\.php$ https://www.example.com/$1 [R=302,L]
# Append the .php extension with an internal rewrite
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^.])+$ $1.php [L]
The directives that append the file extension assumes that existing URLs do not already include a dot. ie. dots only occur when a file extension is applied to the URL.
Upvotes: 2