Change WordPress permalinks on pages to have a .html extension

We are working on a new website built with WordPress MU, BuddyPress and bbPress and our client requested that all of the pages and posts of each MU site have a .html extension. Ok, so posts are easy just head to your “Permalink Settings” page, click the “Custom Structure” radio button and add something like “/%postname%.html”. Pretty simple huh?

So what about pages? I found a great plugin called .html on Pages which will add a .html extension to all of your pages. This plugin will also automatically remove the .html extension from any pages that are nested  as a parent page. Soooo: will turn into

We ran into a problem, well not so much a problem because the plugin does what it is supposed to do, but we want to not add .html to the end of the blog page. We want /blog.html to be just /blog so we had to make a few modifications to the plugin. If you are comfortable with php the mod is small and here it is:

Add the following code where ever you want inside of the plugin. This code filters any instance of /blog.html and returns /blog.

function blog_permalinks_page_link($permalink, $page) {
$pos = strpos($permalink, “/blog.html”);
if ($pos !== false) {
$permalink = str_replace(“/blog.html”,”/blog”,$permalink);
return $permalink;
add_filter( ‘page_link’, ‘blog_permalinks_page_link’, 10, 2 );

Next you will need to alter the html_page_permalink() function and add the following code to the top of it:

$pos = strpos($string, “/blog.html”);
if ($pos !== false) {
switch_to_blog(1);//We are using WPMU if you are not you won’t need this line.
wp_redirect( get_option(‘home’).str_replace(“/blog.html”,”/blog”,$string), 301 );
$pos = strpos($string, “/blog”);
if ($pos !== false) {
$_SERVER[‘REQUEST_URI’] =str_replace(“/blog”,”/blog.html”,$string);
global $wp;

The above code makes the redirect of any hits on /blog.html to /blog (which shouldn’t happen because of the link filter) and hard-codes the request-URL so WordPress thinks it’s pulling from the page /blog.html when it’s now on /blog. That’s it, pretty simple… If you are not good with php you can download the modified plugin here:

I’m sure this plugin could easily be modified to work with other extentions like .htm or .php, which could cut down on the amount of 301 redirects you would have to make when migrating to WordPress which by the way everybody running a blog or basic CMS should be doing! 😉

26 thoughts on “Change WordPress permalinks on pages to have a .html extension

  1. Hey Brian – this is brilliant – thanks. I believe Matt Cutts has mentioned he personally likes to see .html extensions, but the pages should get crawled as long as they don’t end in .exe or .dll

    from his blog: “Sometimes at a conference people will ask me “Does it matter what extension I use for my pages? Does Google prefer .php over .asp, or .html over .htm?” And my answer is “We’re happy to crawl all of these file extensions. It doesn’t matter what you choose between any of those.””

    But I’ve never seen a WP site converted for all .html extensions. I wonder what the impact to ranking might be? Anyway – food for thought. I’m going to experiment with it.

    Cheers – Mal

  2. Many thanks Brian, you did a good job. I added this condition strlen($string)<=strlen('/blog/') because my posts Permalink contains '/blog/'.

    $pos = strpos($string, "/blog.html");
    if ($pos !== false)
    wp_redirect( get_option('home').str_replace("/blog.html","/blog",$string), 301 );
    $pos = strpos($string, "/blog");
    if ($pos !== false && strlen($string)parse_request();

    1. Seems that a portion of this code was truncated at the bottom. I added the condition, “strlen($string)<=strlen('/blog/')" as you suggested and it seems to be working fine but the code sample seems to be different. Did you update your code to something more efficient?

  3. A client rang me up saying that he’d got WP to add the .html extension to pages, but want /blog.html to be just /blog.

    Within a minute of searching I’d found your page, and it does *exactly* what I needed. Kudos – thanks for sharing!

  4. Hi,

    Great! have had this problem for two weeks now, new problem though my links have changed to which i wanted, but now i get a 404 error? for the blog, but not for the posts inside it?

    Any help would be appreciated


    1. Thank you for your comment. I have a customer whose site is very old, he wants wordpress, but all his pages are htm. His page rank is 6 and I don’t want to mess with that!

      I am glad it works!

  5. Hi Brian,

    I am getting a “too many redirects” error when I add this code to the original plugin or use your modified plugin. The only change I made was to have it as “/blog/” (a trailing slash).

    Any advice would be god sent.

    Thanks in advance.

    1. Hi Mika

      Did you finally find how to change the plugin that only pages without children will automatically get a .html extension?


  6. Am switching an old hand-coded site over to WP. All of my pages have a .html extension and I didn’t want to have to redirect every single page of my site.

    This plugin works a dream with WP 3.5.1. Didn’t have to change any of the php files either to get rid of the extension on parent pages. Just used the plugin.

    Thanks for the writeup. One quick Google search and in about 3 minutes I was good to go.

Have a comment?

Your email address will not be published. Required fields are marked *

accessibilityadminaggregationanchorbackupsbookmarksbuddypresscachingcalendarcaret-downcartunifiedcrediblecustommigrationdesigndevecomfriendsgoodgroupsgrowthhostingideasinternationalizationiphoneloyaltymailhealthmessagingArtboard 1migrationsmultiple-sourcesmultisitenotificationsperformancephoneprofilesresearcharrowscalablescrapingsecuresharearrowarrowsourcestreamsupportunifiedupdatesvaultwebsitewordpress