How can i remove .php extension from url [duplicate] - .htaccess
Yes, I've read the Apache manual and searched here. For some reason I simply cannot get this to work. The closest I've come is having it remove the extension, but it points back to the root directory. I want this to just work in the directory that contains the .htaccess file.
I need to do three things with the .htaccess file.
I need it to remove the .php
a. I have several pages that use tabs and the URL looks like page.php#tab - is this possible?
b. I have one page that uses a session ID appended to the URL to make sure you came from the right place, www.domain.example/download-software.php?abcdefg.
Is this possible? Also in doing this, do I need to remove .php from the links in my header nav include file? Should IE "support" be support?
I would like it to force www before every URL, so it's not domain.example, but www.domain.example/page.
I would like to remove all trailing slashes from pages.
I'll keep looking, trying, etc. Would being in a sub directory cause any issues?
Gumbo's answer in the Stack Overflow question How to hide the .html extension with Apache mod_rewrite should work fine.
Re 1) Change the .html to .php
Re a.) Yup, that's possible, just add #tab to the URL.
Re b.) That's possible using QSA (Query String Append), see below.
This should also work in a sub-directory path:
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
Apache mod_rewrite
What you're looking for is mod_rewrite,
Description: Provides a rule-based rewriting engine to rewrite
requested URLs on the fly.
Generally speaking, mod_rewrite works by matching the requested document against specified regular expressions, then performs URL rewrites internally (within the Apache process) or externally (in the clients browser). These rewrites can be as simple as internally translating example.com/foo into a request for example.com/foo/bar.
The Apache docs include a mod_rewrite guide and I think some of the things you want to do are covered in it. Detailed mod_rewrite guide.
Force the www subdomain
I would like it to force "www" before every URL, so its not domain.example but www.domain.example/page
The rewrite guide includes instructions for this under the Canonical Hostname example.
Remove trailing slashes (Part 1)
I would like to remove all trailing slashes from pages
I'm not sure why you would want to do this as the rewrite guide includes an example for the exact opposite, i.e., always including a trailing slash. The docs suggest that removing the trailing slash has great potential for causing issues:
Trailing Slash Problem
Description:
Every webmaster can sing a song about the problem of the trailing
slash on URLs referencing directories. If they are missing, the server
dumps an error, because if you say /~quux/foo instead of /~quux/foo/
then the server searches for a file named foo. And because this file
is a directory it complains. Actually it tries to fix it itself in
most of the cases, but sometimes this mechanism need to be emulated by
you. For instance after you have done a lot of complicated URL
rewritings to CGI scripts etc.
Perhaps you could expand on why you want to remove the trailing slash all the time?
Remove .php extension
I need it to remove the .php
The closest thing to doing this that I can think of is to internally rewrite every request document with a .php extension, i.e., example.com/somepage is instead processed as a request for example.com/somepage.php. Note that proceeding in this manner would would require that each somepage actually exists as somepage.php on the filesystem.
With the right combination of regular expressions this should be possible to some extent. However, I can foresee some possible issues with index pages not being requested correctly and not matching directories correctly.
For example, this will correctly rewrite example.com/test as a request for example.com/test.php:
RewriteEngine on
RewriteRule ^(.*)$ $1.php
But will make example.com fail to load because there is no example.com/.php
I'm going to guess that if you're removing all trailing slashes, then picking a request for a directory index from a request for a filename in the parent directory will become almost impossible. How do you determine a request for the directory 'foobar':
example.com/foobar
from a request for a file called foobar (which is actually foobar.php)
example.com/foobar
It might be possible if you used the RewriteBase directive. But if you do that then this problem gets way more complicated as you're going to require RewriteCond directives to do filesystem level checking if the request maps to a directory or a file.
That said, if you remove your requirement of removing all trailing slashes and instead force-add trailing slashes the "no .php extension" problem becomes a bit more reasonable.
# Turn on the rewrite engine
RewriteEngine on
# If the request doesn't end in .php (Case insensitive) continue processing rules
RewriteCond %{REQUEST_URI} !\.php$ [NC]
# If the request doesn't end in a slash continue processing the rules
RewriteCond %{REQUEST_URI} [^/]$
# Rewrite the request with a .php extension. L means this is the 'Last' rule
RewriteRule ^(.*)$ $1.php [L]
This still isn't perfect -- every request for a file still has .php appended to the request internally. A request for 'hi.txt' will put this in your error logs:
[Tue Oct 26 18:12:52 2010] [error] [client 71.61.190.56] script '/var/www/test.peopleareducks.com/rewrite/hi.txt.php' not found or unable to stat
But there is another option, set the DefaultType and DirectoryIndex directives like this:
DefaultType application/x-httpd-php
DirectoryIndex index.php index.html
Update 2013-11-14 - Fixed the above snippet to incorporate nicorellius's observation
Now requests for hi.txt (and anything else) are successful, requests to example.com/test will return the processed version of test.php, and index.php files will work again.
I must give credit where credit is due for this solution as I found it Michael J. Radwins Blog by searching Google for php no extension apache.
Remove trailing slashes
Some searching for apache remove trailing slashes brought me to some Search Engine Optimization pages. Apparently some Content Management Systems (Drupal in this case) will make content available with and without a trailing slash in URLs, which in the SEO world will cause your site to incur a duplicate content penalty. Source
The solution seems fairly trivial, using mod_rewrite we rewrite on the condition that the requested resource ends in a / and rewrite the URL by sending back the 301 Permanent Redirect HTTP header.
Here's his example which assumes your domain is blamcast.net and allows the the request to optionally be prefixed with www..
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?blamcast\.net$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
Now we're getting somewhere. Lets put it all together and see what it looks like.
Mandatory www., no .php, and no trailing slashes
This assumes the domain is foobar.example and it is running on the standard port 80.
# Process all files as PHP by default
DefaultType application/x-httpd-php
# Fix sub-directory requests by allowing 'index' as a DirectoryIndex value
DirectoryIndex index index.html
# Force the domain to load with the www subdomain prefix
# If the request doesn't start with www...
RewriteCond %{HTTP_HOST} !^www\.foobar\.com [NC]
# And the site name isn't empty
RewriteCond %{HTTP_HOST} !^$
# Finally rewrite the request: end of rules, don't escape the output, and force a 301 redirect
RewriteRule ^/?(.*) http://www.foobar.example/$1 [L,R,NE]
#get rid of trailing slashes
RewriteCond %{HTTP_HOST} ^(www.)?foobar\.com$ [NC]
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
The 'R' flag is described in the RewriteRule directive section. Snippet:
redirect|R [=code] (force redirect) Prefix Substitution with
http://thishost[:thisport]/ (which makes the new URL a URI) to force
a external redirection. If no code is given, a HTTP response of 302
(MOVED TEMPORARILY) will be returned.
Final Note
I wasn't able to get the slash removal to work successfully. The redirect ended up giving me infinite redirect loops. After reading the original solution closer I get the impression that the example above works for them because of how their Drupal installation is configured. He mentions specifically:
On a normal Drupal site, with clean URLs enabled, these two addresses
are basically interchangeable
In reference to URLs ending with and without a slash. Furthermore,
Drupal uses a file called .htaccess to tell your web server how to
handle URLs. This is the same file that enables Drupal's clean URL
magic. By adding a simple redirect command to the beginning of your
.htaccess file, you can force the server to automatically remove any
trailing slashes.
In addition to other answers above,
You may also try this to remove .php extensions completely from your file and to avoid infinite loop:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [NC,L]
This code will work in Root/.htaccess,
Be sure to change the RewriteBase if you want to place this to a htaccess file in sub directory.
On Apache 2.4 and later, you can also use the END flag to prevent infinite loop error. The following example works same as the above on Apache 2.4,
RewriteEngine on
RewriteRule ^(.+)\.php$ /$1 [R,L]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ /$1.php [NC,END]
The following code works fine for me:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
After changing the parameter AllowOverride from None to All in /etc/apache2/apache2.conf (Debian 8), following this, the .htaccess file just must contain:
Options +MultiViews
AddHandler php5-script php
AddType text/html php
And it was enough to hide .php extension from files
I've ended up with the following working code:
RewriteEngine on
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [NC,L]
Here's a method if you want to do it for just one specific file:
RewriteRule ^about$ about.php [L]
Ref: http://css-tricks.com/snippets/htaccess/remove-file-extention-from-urls/
Try this
The following code will definitely work
RewriteEngine on
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NC,L,R]
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php [NC,L]
Not sure why the other answers didn't work for me but this code I found did:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
That is all that is in my htaccess and example.com/page shows example.com/page.php
To remove the .php extension from a PHP file for example yoursite.example/about.php to yoursite.example/about: Open .htaccess (create new one if not exists) file from root of your website, and add the following code.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
To remove the .html extension from a HTML file for example yoursite.example/about.html to yoursite.example/about: Open .htaccess (create new one if not exists) file from root of your website, and add the following code.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Reference: How to Remove PHP Extension from URL
Try this:-
RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule !.*\.php$ %{REQUEST_FILENAME}.php [QSA,L]
I found 100% working Concept for me:
# Options is required by Many Hosting
Options +MultiViews
RewriteEngine on
# For .php & .html URL's:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule ^([^\.]+)$ $1.html [NC,L]
Use this code in Root of your website .htaccess file like :
offline - wamp\www\YourWebDir
online - public_html/
If it doesn't work correct, then change the settings of your Wamp
Server: 1) Left click WAMP icon 2) Apache 3) Apache Modules 4) Left
click rewrite_module
Here is the code that I used to hide the .php extension from the filename:
## hide .php extension
# To redirect /dir/foo.php to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L,NC]
Note: R=301 is for permanent redirect and is recommended to use for SEO purpose. However if one wants just a temporary redirect replace it with just R
Try
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [L]
If you're coding in PHP and want to remove .php so you can have a URL like:
http://yourdomain.example/blah -> which points to /blah.php
This is all you need:
<IfModule mod_rewrite.c>
RewriteRule ^(.+)/$ http://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
If your URL in PHP like http://yourdomain.example/demo.php than comes like
http://yourdomain.example/demo
This is all you need:
create file .htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
#RewriteRule ^([^\.]+)$ $1.html [NC,L]
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$"
RewriteRule .* - [L,R=404]
Related
Rewrite multiple rules in .htaccess / remove .html extension [duplicate]
How to remove .html from the URL of a static page? Also, I need to redirect any url with .html to the one without it. (i.e. www.example.com/page.html to www.example.com/page ).
I think some explanation of Jon's answer would be constructive. The following: RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d checks that if the specified file or directory respectively doesn't exist, then the rewrite rule proceeds: RewriteRule ^(.*)\.html$ /$1 [L,R=301] But what does that mean? It uses regex (regular expressions). Here is a little something I made earlier... I think that's correct. NOTE: When testing your .htaccess do not use 301 redirects. Use 302 until finished testing, as the browser will cache 301s. See https://stackoverflow.com/a/9204355/3217306 Update: I was slightly mistaken, . matches all characters except newlines, so includes whitespace. Also, here is a helpful regex cheat sheet Sources: http://community.sitepoint.com/t/what-does-this-mean-rewritecond-request-filename-f-d/2034/2 https://mediatemple.net/community/products/dv/204643270/using-htaccess-rewrite-rules
To remove the .html extension from your urls, you can use the following code in root/htaccess : RewriteEngine on RewriteCond %{THE_REQUEST} /([^.]+)\.html [NC] RewriteRule ^ /%1 [NC,L,R] RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule ^ %{REQUEST_URI}.html [NC,L] NOTE: If you want to remove any other extension, for example to remove the .php extension, just replace the html everywhere with php in the code above. Also see this How to remove .html and .php from URLs using htaccess` .
This should work for you: #example.com/page will display the contents of example.com/page.html RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule ^(.+)$ $1.html [L,QSA] #301 from example.com/page.html to example.com/page RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*\.html\ HTTP/ RewriteRule ^(.*)\.html$ /$1 [R=301,L]
With .htaccess under apache you can do the redirect like this: RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)\.html$ /$1 [L,R=301] As for removing of .html from the url, simply link to the page without .html page
You will need to make sure you have Options -MultiViews as well. None of the above worked for me on a standard cPanel host. This worked: Options -MultiViews RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^([^\.]+)$ $1.html [NC,L]
For those who are using Firebase hosting none of the answers will work on this page. Because you can't use .htaccess in Firebase hosting. You will have to configure the firebase.json file. Just add the line "cleanUrls": true in your file and save it. That's it. After adding the line firebase.json will look like this : { "hosting": { "public": "public", "cleanUrls": true, "ignore": [ "firebase.json", "**/.*", "**/node_modules/**" ] } }
Thanks for your replies. I have already solved my problem. Suppose I have my pages under http://www.yoursite.com/html, the following .htaccess rules apply. <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /html/(.*).html\ HTTP/ RewriteRule .* http://localhost/html/%1 [R=301,L] RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /html/(.*)\ HTTP/ RewriteRule .* %1.html [L] </IfModule>
Good question, but it seems to have confused people. The answers are almost equally divided between those who thought Dave (the OP) was saving his HTML pages without the .html extension, and those who thought he was saving them as normal (with .html), but wanting the URL to show up without. While the question could have been worded a little better, I think it’s clear what he meant. If he was saving pages without .html, his two question (‘how to remove .html') and (how to ‘redirect any url with .html’) would be exactly the same question! So that interpretation doesn’t make much sense. Also, his first comment (about avoiding an infinite loop) and his own answer seem to confirm this. So let’s start by rephrasing the question and breaking down the task. We want to accomplish two things: Visibly remove the .html if it’s part of the requested URL (e.g. /page.html) Point the cropped URL (e.g. /page) back to the actual file (/page.html). There’s nothing difficult about doing either of these things. (We could achieve the second one simply by enabling MultiViews.) The challenge here is doing them both without creating an infinite loop. Dave’s own answer got the job done, but it’s pretty convoluted and not at all portable. (Sorry Dave.) Łukasz Habrzyk seems to have cleaned up Anmol’s answer, and finally Amit Verma improved on them both. However, none of them explained how their solutions solved the fundamental problem—how to avoid an infinite loop. As I understand it, they work because THE_REQUEST variable holds the original request from the browser. As such, the condition (RewriteCond %{THE_REQUEST}) only gets triggered once. Since it doesn’t get triggered upon a rewrite, you avoid the infinite loop scenario. But then you're dealing with the full HTTP request—GET, HTTP and all—which partly explains some of the uglier regex examples on this page. I’m going to offer one more approach, which I think is easier to understand. I hope this helps future readers understand the code they’re using, rather than just copying and pasting code they barely understand and hoping for the best. RewriteEngine on # Remove .html (or htm) from visible URL (permanent redirect) RewriteCond %{REQUEST_URI} ^/(.+)\.html?$ [nocase] RewriteRule ^ /%1 [L,R=301] # Quietly point back to the HTML file (temporary/undefined redirect): RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule ^ %{REQUEST_URI}.html [END] Let’s break it down… The first rule is pretty simple. The condition matches any URL ending in .html (or .htm) and redirects to the URL without the filename extension. It's a permanent redirect to indicate that the cropped URL is the canonical one. The second rule is simple too. The first condition will only pass if the requested filename is not a valid directory (!-d). The second will only pass if the filename refers to a valid file (-f) with the .html extension added. If both conditions pass, the rewrite rule simply adds ‘.html’ to the filename. And then the magic happens… [END]. Yep, that’s all it takes to prevent an infinite loop. The Apache RewriteRule Flags documentation explains it: Using the [END] flag terminates not only the current round of rewrite processing (like [L]) but also prevents any subsequent rewrite processing from occurring in per-directory (htaccess) context.
Resorting to using .htaccess to rewrite the URLs for static HTML is generally not only unnecessary, but also bad for you website's performance. Enabling .htaccess is also an unnecessary security vulnerability - turning it off eliminates a significant number of potential issues. The same rules for each .htaccess file can instead go in a <Directory> section for that directory, and it will be more performant if you then set AllowOverride None because it won't need to check each directory for a .htaccess file, and more secure because an attacker can't change the vhost config without root access. If you don't need .htaccess in a VPS environment, you can disable it entirely and get better performance from your web server. All you need to do is move your individual files from a structure like this: index.html about.html products.html terms.html To a structure like this: index.html about/index.html products/index.html terms/index.html Your web server will then render the appropriate pages - if you load /about/, it will treat that as /about/index.html. This won't rewrite the URL if anyone visits the old one, though, so it would need redirects to be in place if it was retroactively applied to an existing site.
I use this .htacess for removing .html extantion from my url site, please verify this is correct code: RewriteEngine on RewriteBase / RewriteCond %{http://www.proofers.co.uk/new} !(\.[^./]+)$ RewriteCond %{REQUEST_fileNAME} !-d RewriteCond %{REQUEST_fileNAME} !-f RewriteRule (.*) /$1.html [L] RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^.]+)\.html\ HTTP RewriteRule ^([^.]+)\.html$ http://www.proofers.co.uk/new/$1 [R=301,L]
Making my own contribution to this question by improving the answer from #amit-verma (https://stackoverflow.com/a/34726322/2837434) : In my case I had an issue where RewriteCond %{REQUEST_FILENAME}.html -f was triggering (believing the file existed) even when I was not expecting it : %{REQUEST_FILENAME}.html was giving me /var/www/example.com/page.html for all these cases : www.example.com/page (expected) www.example.com/page/ (also quite expected) www.example.com/page/subpage (not expected) So the file it was trying to load (believing if was /var/www/example.com/page.html) were : www.example.com/page => /var/www/example/page.html (ok) www.example.com/page/ => /var/www/example/page/.html (not ok) www.example.com/page/subpage => /var/www/example/page/subpage.html (not ok) Only the first one is actually pointing to an existing file, other requests were giving me 500 errors as it kept believing the file existed and appending .html repeatedly. The solution for me was to replace RewriteCond %{REQUEST_FILENAME}.html -f with RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.html -f Here is my entire .htaccess (I also added a rule to redirect the user from /index to /) : # Redirect "/page.html" to "/page" (only if "/pages.html" exists) RewriteCond %{REQUEST_FILENAME} -f RewriteCond %{THE_REQUEST} /(.+)\.html [NC] RewriteRule ^(.+)\.html$ /$1 [NC,R=301,L] # redirect "/index" to "/" RewriteRule ^index$ / [NC,R=301,L] # Load "/page.html" when requesting "/page" (only if "/pages.html" exists) RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.html -f RewriteRule ^ /%{REQUEST_URI}.html [QSA,L] Here is a result example to help you understand all the cases : Considering I have only 2 html files on my server (index.html & page.html) www.example.com/index.html => redirects to www.example.com www.example.com/index => redirects to www.example.com www.example.com => renders /var/www/example.com/index.html www.example.com/page.html => redirects to www.example.com/page www.example.com/page => renders /var/www/example.com/page.html www.example.com/page/subpage => returns 404 not found www.example.com/index.html/ => returns 404 not found www.example.com/page.html/ => returns 404 not found www.example.com/test.html => returns 404 not found No more 500 errors 🚀 Also, just to help you debug your redirections, consider disabling the network cache in your browser (as old 301 redirections my be in cache, wich may cause some headaches 😅):
first create a .htaccess file and set contents to - RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.html -f RewriteRule ^(.*)$ $1.html next remove .html from all your files eg. test.html became just test and also if you wanna open a file from another file then also remove .html from it and just file name
Use a hash tag. May not be exactly what you want but it solves the problem of removing the extension. Say you have a html page saved as about.html and you don't want that pesky extension you could use a hash tag and redirect to the correct page. switch(window.location.hash.substring(1)){ case 'about': window.location = 'about.html'; break; } Routing to yoursite.com#about will take you to yoursite.com/about.html. I used this to make my links cleaner.
To remove the .html extension from your URLs, you can use the following code in root/htaccess : #mode_rerwrite start here RewriteEngine On # does not apply to existing directores, meaning that if the folder exists on server then don't change anything and don't run the rule. RewriteCond %{REQUEST_FILENAME} !-d #Check for file in directory with .html extension RewriteCond %{REQUEST_FILENAME}\.html !-f #Here we actually show the page that has .html extension RewriteRule ^(.*)$ $1.html [NC,L] Thanks
For this, you have to rewrite the URL from /page.html to /page You can easily implement this on any extension like .html .php etc RewriteRule ^(.*).html$ $1.html [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^([^\.]+)$ $1.html [NC,L] You will get a URL something like this: example.com/page.html to example.com/page Please note both URLs below will be accessible example.com/page.html and example.com/page If you don't want to show page.html Try this RewriteRule ^(.*).html$ $1 [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^([^\.]+)$ $1.html [NC,L] More info here
If you have a small static website and HTML files are in the root directory. Open every HTML file and make the next changes: Replace href="index.html" with href="/". Remove .html in all local links. For example: "href="about.html"" should look like "href="about"".
RewriteEngine On RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /html/(.*).html\ HTTP/ RewriteRule .* https://example.com/html/%1 [R=301,L] RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /html/(.*)\ HTTP/ RewriteRule .* %1.html [L] it might work because its working in my case
RewriteRule /(.+)(\.html)$ /$1 [R=301,L] Try this :) don't know if it works.
htaccess RewriteRule *.php to /*/
I just can't find correct solution for what I need, so I hope someone will be able to help me here. I now have website with this files: /admin/ /images/ /js/ about.php index.php news.php questions.php So my URLs now are: www.mydomain.com/about.php www.mydomain.com/news.php ... I would like to have www.mydomain.com/about/, www.mydomain.com/news/,... I have tried many things which I found but none of them works like it should or it messes something else up. The closest I got to is this: RewriteRule about/ about.php RewriteRule about about.php But this also messes up if I use some image in code containing name about (example images/about-me.jpg) - probably because of second statement.
Enable mod_rewrite and .htaccess through httpd.conf and then put this code in your .htaccess under DOCUMENT_ROOT directory: Options +FollowSymLinks -MultiViews # Turn mod_rewrite on RewriteEngine On RewriteBase / ## hide .php extension # To externally redirect /dir/foo.php to /dir/foo RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC] RewriteRule ^ %1 [R,L,NC] ## To internally forward /dir/foo to /dir/foo.php RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ^ %{REQUEST_FILENAME}.php [L]
To make life simpler I would stop using the directory based URL /about/ and use a simpler file base URL /about That extra slash moves the page into a sub directory and all your relative references in the page will break. Alternatively you can change all your links, includes and image URLs to make sure they all are relative to the root of the domain. You do this by always including a slash (/) before the URL or making them a full URL. And make your rule more specific: RewriteRule ^/about$ about.php Those extra ^$ indicate start and end so it has to be an exact match.
this worked for me RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(about)$ about.php
mod rewrite to remove file extension, add trailing slash, remove www and redirect to 404 if no file/directory is available
I would like to create rewrite rules in my .htaccess file to do the following: When accessed via domain.com/abc.php: remove the file extension, append a trailing slash and load the abc.php file. url should look like this after rewrite: domain.com/abc/ When accessed via domain.com/abc/: leave the url as is and load abc.php When accessed via domain.com/abc: append trailing slash and load abc.php. url should look like this after rewrite: domain.com/abc/ Remove www Redirect to 404 page (404.php) when accessed url doesn't resolve to folder or file, e.g. when accessing either domain.com/nothingthere.php or domain.com/nothingthere/ or domain.com/nothingthere Make some permanent 301 redirects from old urls to new ones (e.g. domain.com/abc.html to domain.com/abc/) All php files sit in the document root directory, but if there is a solution that would make urls such as domain.com/abc/def/ (would load domain.com/abc/def.php) also work it would be great as well, but not necessary So here is what I have at the moment (thrown together from various sources and samples from around the web <IfModule mod_rewrite.c> RewriteCond %{HTTPS} !=on # redirect from www to non-www RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L] # remove php file extension RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{THE_REQUEST} ^GET\ /[^?\s]+\.php RewriteRule (.*)\.php$ /$1/ [L,R=301] # add trailing slash RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^.*[^/]$ /$0/ [L,R=301] # resolve urls to matching php files RewriteCond %{REQUEST_FILENAME} !-d RewriteRule (.*)/$ $1.php [L] With this the first four requirements seem to work, whether I enter domain.com/abc.php, domain.com/abc/ or domain.com/abc, the final url always ends up being domain.com/abc/ and domain.com/abc.php is loaded. When I enter a url that resolves to a file that doesn't exists I'm getting an error 310 (redirect loop), when really a 404 page should be loaded. Additionally I haven't tried if subfolders work, but as I said, that's low priority. I'm pretty sure I can just slap the permanent 301 redirects for legacy urls on top of that without any issues as well, just wanted to mention it. So the real issue is really the non working 404 page.
I've had problems with getting ErrorDocument to work reliably with rewrite errors, so I tend to prefer to handle invalid pages correctly in my rewrite cascade. I've tried to cover a fully range of test vectors with this. Didn't find any gaps. Some general points: You need to use the DOCUMENT_ROOT environment variable in this. Unfortunately if you use a shared hosting service then this isn't set up correctly during rewrite execution, so hosting providers set up a shadow variable to do the same job. Mine uses DOCUMENT_ROOT_REAL, but I've also come across PHP_DOCUMENT_ROOT. Do a phpinfo to find out what to use for your service. There's a debug info rule that you can trim as long as you replace DOCROOT appropriately You can't always use %{REQUEST_FILENAME} where you'd expect to. This is because if the URI maps to DOCROOT/somePathThatExists/name/theRest then the %{REQUEST_FILENAME} is set to DOCROOT/somePathThatExists/name rather than the full pattern equivalent to the rule match string. This is "Per Directory" so no leading slashes and we need to realise that the rewrite engine will loop on the .htaccess file until a no-match stop occurs. This processes all valid combinations and at the very end redirects to the 404.php which I assume sets the 404 Status as well as displaying the error page. It will currently decode someValidScript.php/otherRubbish in the SEO fashion, but extra logic can pick this one up as well. So here is the .htaccess fragment: Options -Indexes -MultiViews AcceptPathInfo Off RewriteEngine On RewriteBase / ## Looping stop. Not needed in Apache 2.3 as this introduces the [END] flag RewriteCond %{ENV:REDIRECT_END} =1 RewriteRule ^ - [L,NS] ## 302 redirections ## RewriteRule ^ - [E=DOCROOT:%{ENV:DOCUMENT_ROOT_REAL},E=URI:%{REQUEST_URI},E=REQFN:%{REQUEST_FILENAME},E=FILENAME:%{SCRIPT_FILENAME}] # redirect from HTTP://www to non-www RewriteCond %{HTTPS} !=on RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L] # remove php file extension on GETs (no point in /[^?\s]+\.php as rule pattern requires this) RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_METHOD} =GET RewriteRule (.*)\.php$ $1/ [L,R=301] # add trailing slash RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^.*[^/]$ $0/ [L,R=301] # terminate if file exists. Note this match may be after internal redirect. RewriteCond %{REQUEST_FILENAME} -f RewriteRule ^ - [L,E=END:1] # terminate if directory index.php exists. Note this match may be after internal redirect. RewriteCond %{REQUEST_FILENAME} -d RewriteCond %{ENV:DOCROOT}/$1/index.php -f RewriteRule ^(.*)(/?)$ $1/index.php [L,NS,E=END:1] # resolve urls to matching php files RewriteCond %{ENV:DOCROOT}/$1.php -f RewriteRule ^(.*?)/?$ $1.php [L,NS,E=END:1] # Anything else redirect to the 404 script. This one does have the leading / RewriteRule ^ /404.php [L,NS,E=END:1] Enjoy :-)
You'll probably want to check if the php file exists before adding the tailing slash. RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ^.*[^/]$ /$0/ [L,R=301] or if you really want a tailing slash for all 404 pages (so /image/error.jpg will become /images/error.jpg/, which I think is weird): RewriteCond %{ENV:REDIRECT_STATUS} !200 RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^.*[^/]$ /$0/ [L,R=301]
I came up with this: DirectorySlash Off RewriteEngine on Options +FollowSymlinks ErrorDocument 404 /404.php #if it's www # redirect to non-www. RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] RewriteRule ^ http://%1%{REQUEST_URI} [L,R=301,QSA] #else if it has slash at the end, and it's not a directory # serve the appropriate php RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)/$ /$1.php [L,QSA] #else if it's an existing file, and it's not php or html # serve the content without rewrite RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteCond %{REQUEST_FILENAME} -f RewriteCond %{REQUEST_URI} !(\.php)|(\.html?)$ RewriteRule ^ - [L,QSA] #else # strip php/html extension, force slash RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteRule ^(.*?)((\.php)|(\.html?))?/?$ /$1/ [L,NC,R=301,QSA] Certainly not very elegant (env:redirect_status is quite a hack), but it passes my modest tests. Unfortunately I can't test the www redirection, as I'm on localhost, and has no real access to a server, but that part should work too. You see, I used the ErrorDocument directive to specify the error page, and used the DirectorySlash Off request to make sure Apache doesn't interfere with the slash-appending fun. I also used the QSA (Query String Append) flag that, well, appends the query string to the request so that it's not lost. It looks kind of silly after the trailing slash, but anyhow. Otherwise it's pretty straightforward, and I think the comments explain it pretty well. Let me know if you run into any trouble with it.
Create a folder under the root of the domain Place a .htaccess in the above folder as RewriteRule ^$ index.php Parse the URL With PHP coding you can now strip the URL or file extension as required
remove php extension, stop access of url with .php extension and remove trailing slashes
I want my urls to be extensionless, so no .php extension, I also want there not to be an opportunity to access the URL with a trailing slash. The following removes php extension and thens redirects to the extensionless url if you try to access it with .php I started writing a rule to stop you accessing with a / and redirect, but it does not work, any help? #this removes php extension RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^([^\.]+)$ $1.php [NC,L] # stops you accessing url with.php RewriteCond %{THE_REQUEST} ^[A-Z]+\ /([^.?\ ]+)\.php RewriteRule ^([^.]+)\.php(/.+)?$ /$1%{PATH_INFO} [R=301] # stops you accessing url with / **DOESNT WORK** RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)/$ /$1 [R=301,L]
You're looking at things backwards: the first rule you have doesn't "remove the php extension", it adds it to URLs that don't already have it (technically, any that don't contain a period). I think you want something more like this: RewriteEngine On RewriteBase / # Remove .php from any URLs that contain it, using an external 301 redirect RewriteCond %{QUERY_STRING} !^no-redirect-loop(&|$) RewriteRule ^(.*)\.php$ $1 [NS,R=301,L] # Now add it back internally RewriteCond %{QUERY_STRING} !^no-redirect-loop(&|$) RewriteRule ^(.*)$ $1.php?no-redirect-loop [NS,QSA] Edit: While debugging another similar answer, I realized that the previous solution I posted here wasn't going to work in an .htaccess file. I've edited the example code above to use a rather ugly kluge for breaking redirect loops instead. A side effect of the kluge is that all scripts will see an extra empty URL parameter named no-redirect-loop.
500 error for clean url mod re-write
Thanks to everyone who has helped me with my clean URL quest. I'm almost there but want to lick this last thing. .htaccess RewriteEngine on #REMOVE THIS LINE ON SITE LAUNCH! RewriteBase /~accountName/ #Hide .php extensions for cleaner URLS RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\.php -f RewriteRule ^(.*)$ $1.php #calendar-expanded REST-ful URLs RewriteRule ^calendar-expanded(/.*)?$ calendar-expanded.php$1 [L] Options All -Indexes <IfModule mod_security.c> SecFilterEngine Off SecFilterScanPOST Off </IfModule> # propagate php.ini file to all sub-directories suPHP_ConfigPath /home/accountName/public_html/php.ini my working url www.example.com/calendar-expanded/4/mother-mother-in-concert/ a broken url www.example.com/calendar/12/another-band-live/ There is no mod re-write for calendar/ obviously. My question is, do I absolutely need a rule for every page to avoid internal server errors if someone accidentally browses to the wrong page? The broken url is an example of that. I'd really love for the browser to return a 404 error instead. I'm looking for a cond/rule that will cover "all other" urls except calendar-expanded. Is this doable? Thanks. (#Gumbo I'm looking hopefully in your direction!)
I could reconstruct this behavior and trace it back to this condition: RewriteCond %{REQUEST_FILENAME}\.php -f Here REQUEST_FILENAME does only contain the filesystem path to calendar within the same directory. And that appended with .php is an existing file so the condition is true. But $1 does contain the full requested URL path that is now appended .php. This keeps repeating until the internal counter exceeds its limit. A solution to that is to use %{REQUEST_FILENAME}.php in the substitution as well: RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ^ %{REQUEST_FILENAME}.php
Could you create a rule that matches everything and just have it at the bottom? The rewrite engine gives precedence to rules based on the order in which they appear in the .htaccess file.