How to Remove URL Extension and Force
Trailing Slash in .htaccess
July 16, 2019 by Radu
I had my small presentation site – Radu.link – on WordPress. But since it’s static, I decided to
recreate it with HTML and Bootstrap, which is much better.
While it’s much better, it’s also a bit harder because you have to take care of things yourself,
such as removing the URL extensions (e.g. .html, .php), adding a trailing slash at the end, and
performing proper redirects.
I thought it would be easy to find a proper code for .htaccess, but it wasn’t. I think I spent a
couple of hours finding something that works properly.
One code was removing my .html extension, adding the trailing slash at the end, but wasn’t
forcing it by performing a redirect.
From this:
https://example.com/page
to this:
https://example.com/page/
Another code was removing the extension, adding a trailing slash, performing the redirect, but
for some reason, it was still possible to manually access the links with the .html extension.
And so on…
via GIPHY
It’s important to have a proper redirection to avoid duplicate content issues.
Google’s John Mueller also recommends being consistent and either use a trailing slash at the
end or not.
Note that trailing slashes on hostnames (e.g. https://example.com/) don’t matter, as it’s
explained here.
You can also use a canonical URL to solve duplicate content issues, but a redirection is your best
bet, especially if you want to pass the link juice from one link to another.
That being said, I’m writing this post to, hopefully, spare you a lot of time searching for a proper
.htaccess code that takes care of all 3 things.
Remove URL Extension and Force Trailing Slash
Note: If you try it on your localhost, it probably won’t work.
I’ve used this code to remove the .html extension, but it works for other extensions as well, such
as .php, which was the one used by the person who provided the code on Stack Overflow.
So, add this code in your .htaccess file and replace the URL extension with your own.
## Remove html extension
RewriteEngine On
RewriteBase /
# To externally redirect /dir/foo.html to /dir/foo
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.html [NC]
RewriteRule ^ %1/ [R=301,L]
# Add a trailing slash at the end
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !/$
RewriteRule . %{REQUEST_URI}/ [L,R=301]
# To internally forward /dir/foo to /dir/foo.html
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.*?)/?$ $1.html [L]
This code will:
Remove the URL extension;
Add a trailing slash at the end;
Force the trailing slash with a 301 redirect to avoid duplicate content issues.
Note that the original code from the link doesn’t have a 301 redirect added in the first rule (i.e.
[R=301,L]).
It has [R,L], which will perform a 302 redirect, which is a temporary one, not a permanent one
like 301.
In cases like this, it’s best to use 301 to tell search engines that the link is permanently moved.
If You’re Having Problems with Your Content
After you add the code, clear your browser’s cache or check the site using an Incognito/Private
window.
Except for your homepage, your CSS styles will probably be missing and you’ll only have the
HTML formatting.
The best way to solve this is to add this somewhere in your <head> section:
<base href="/">
Otherwise, you’ll have to use absolute URL paths in your code to solve the issue.
For example, this:
<link href="https://example.com/path/to/style.css" rel="stylesheet">
instead of this:
<link href="path/to/style.css" rel="stylesheet">
Or, if your base is a subdirectory, you can use it like this:
<link href="../style.css" rel="stylesheet">
Update
I’ve done the same thing for my first and freshly launched project (now sold), called WP Flunky,
which is based on PHP.
But, the problem is that the <base> tag doesn’t work with things like anchors (<a
href="#example">) or query strings (example.com/page/?id=1).
If you have a PHP page that generates query strings, it will be redirected to the base
(example.com/?id=1).
So, you either have to use absolute URLs, or find a workaround to keep using base with relative
URLs.
I went ahead and created a constant, added it in a config.php file, and used that in my paths to
create absolute URLs and finish with the nuisance once and for all.
This is the constant:
<?php
define("BASE_URL", "https://example.com/")
This is how I used it in the links:
<img src="<?php echo BASE_URL; ?>assets/images/image.png">
Should have done that from the start, but I’m still a rookie and still learning from my mistakes.
That’s a Wrap
I hope this post helped you out, and you managed to remove the URL extension and force a
trailing slash at the end of it.
If you’ve found a better code for .htaccess, please share it with the rest of us in the comments.
If you have questions or thoughts, please leave a comment or send me a message using the
contact page.
Don’t forget to share the post to help out others!
Post navigation
How to Enable Word Wrap to Disable Horizontal Scrolling in VS Code
How to Remove Alternate Emails from Google G Suite Account
https://wp-mix.com/category/htaccess/
https://www.crucialhosting.com/knowledgebase/htaccess-apache-rewrites-examples