How to Remove URL Extension and Force Trailing Slash in .htaccess

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…

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

Advertisement
Smartest Way To Save More With DealFuel

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!

Advertisement
Design Bundles and Deals

2 thoughts on “How to Remove URL Extension and Force Trailing Slash in .htaccess”

  1. This is Stripe.com ApplePay domain registration and verification issue:

    “We were unable to verify that you control the domain mydomain.com. When we tried to request https://mydomain.com/.well-known/apple-developer-merchantid-domain-association, it redirected to https://mydomain.com/.well-known/apple-developer-merchantid-domain-association/. The verification file must be served as a 200 at https://mydomain.com/.well-known/apple-developer-merchantid-domain-association to register mydomain.com. Did you mean to register mydomain.com? For more information, see https://stripe.com/docs/stripe-js/elements/payment-request-button#verifying-your-domain-with-apple-pay. ”

    I don’t get what Strip wants me to do and why. Remove the trailing slash? And is it safe to do it? How do I do that?

    • I think you should contact them and find out what exactly do they request.

      From what I can tell from the verification issue and documentation, they don’t like that redirection from non-trailing slash to trailing slash. They might want the link to be exactly like it’s described in their documentation – without a trailing slash at the end.

      So, you might have to remove that redirection in order to make the issue go away.

      Is it safe? How to do it? It depends on your environment/platform and the redirection codes that you’re using. If you redirect through nginx, .htaccess, php, etc. I recommend asking for some professional help if you don’t know how to do it yourself.

      But, I’d contact Stripe first to see if there’s a workaround.

Leave a Comment

Tweet
Share