Remove PHP extension from URL
I always found the .php
at the end of some website pages I visit (and when I used WordPress) very unattractive and annoying. I wanted to remove it and after some research and experimentation, I found several robust ways to accomplish this. Since I work with both Apache and Nginx servers in my projects, I’ll share approaches for both.
The first thing is to make sure what type of server you’re working with and what level of access you have. If you’re on a shared host, you’ll likely be dealing with Apache and its .htaccess
files. But if you’re running your own VPS or dedicated server (which I personally prefer for serious projects), you’ve got more flexibility and can use either Apache or Nginx with full configuration access.
For Apache servers (which is super common with shared hosting), we need to create the .htaccess
file in the root directory. You can create the file using any text editor you’re comfortable with - I personally use VS Code, but honestly, any editor will do. If you’re stuck with FTP access on shared hosting, you can use that too, though I strongly recommend using SFTP or SSH if your host provides it. I learned this the hard way when I once accidentally corrupted a .htaccess
file over plain FTP - not fun debugging that one!
P.S: I don’t recommend using FTP protocol to create the .htaccess
file. It’s better to use SFTP or SSH protocol. I know that this might not be possible for some people on some shared hosting plans, but if you have the option, I recommend using SFTP or SSH protocol.
For Apache, here’s the magical configuration I use (whether in .htaccess
or in the virtualhost configuration if you have server access):
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)$ $1.html
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.htm -f
RewriteRule ^(.*)$ $1.htm
Now, if you’re running Nginx (which I often prefer for its performance and configuration clarity), things work a bit differently. You won’t find any .htaccess
files here. If you’re on shared hosting with Nginx, you’ll need to talk to your hosting provider since Nginx doesn’t support per-directory configuration files. But if you’re running your own server (which I assume many of you are), you can add this to your server block configuration:
location / {
try_files $uri $uri/ @extensionless-php;
index index.html index.php;
}
location @extensionless-php {
rewrite ^(.*)$ $1.php last;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}
This code tells the server to rewrite any URL that ends in .php
, .html
, or .htm
to the same URL without the extension. For example, if a visitor requests the URL www.melashri.net/about.php, the server will rewrite the URL to www.melashri.net/about and serve the content from the about.php file. Pretty neat, right?
One thing I learned the hard way about removing extensions - it can sometimes confuse search engines. So here’s a pro tip: use the rel=“canonical” tag to help search engines understand your URLs better. It’s as simple as adding this to your page’s head section:
<link rel="canonical" href="https://www.melashri.net/about" />
If you’re working with WordPress or another CMS, you can usually add this through your theme files or plugins. For static sites (which is what I use), just pop it right into your HTML files.
And I think it would be useful to restart your web server if you are running your own. This can be done using systemctl restart <service>
command.
sudo systemctl restart apache2 # for Apache
# or
sudo systemctl restart nginx # for Nginx
I’ve been using this setup for years now, and it’s worked great across multiple projects. The URLs look cleaner, more professional, and it hasn’t caused any SEO issues thanks to the canonical tags.