Get WordPress Permalinks Working with Windows, IIS, and ISAPI Rewrite

The eternal battle is over, mostly: getting your WordPress permalinks to work on your Windows IIS web server with ISAPI Rewrite installed.

Some Requirments.

  1. Sorry, but you’re going to need ISAPI Rewrite 3. You can download a lite version for free, but I suggest purchasing it. I’ve used ISAPI Rewrite for years now with clients on Windows hosting, and it’s the bees knees. Version 3 is now supporting many common mod_rewrite directives, which is sweet.
  2. Your .htaccess file. Here’s an example that has worked with WordPress 2.7.x, ISAPI Rewrite 3, and Windows Server 2003/IIS 6.0:
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule .* /index.php [L]

How it works.
Even with ISAPI Rewrite, your WordPress permalinks most likely will be broken without the ugly, prepended /index.php/. The problem is that the REQUEST_URI server variable is not sent by IIS or ISAPI Rewrite. This plugin solves this.

This solution is more elegant that changing the WordPress core files because it allows you to easily upgrade WordPress without additional maintenance.

Download and Documentation.
You can download ISAPI Rewriter from the WordPress Plugin directory.

You can view documentation at the ISAPI Rewrite plugin page.


  1. Seagoat says…

    I followed all the steps outlined above (for a client’s site), and the rewrite works, but somehow the stylesheet gets nuked in the process. If I undo all the changes, my styles come back, but then of course I don’t have the index.php-less URLs. :-/ Any thoughts?

  2. andy says…

    @Seagoat what version of ISAPI Rewrite are you using? Needs to be 3.0

    Try changing it to this:

    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule .* /index.php [L]

    I may have made a typo in the .htaccess configs and left the underscore out of the server variable within the rewrite conditions. I’ll update the post!

  3. Seagoat says…

    Thanks for getting back to me so quickly! I am indeed using 3.0, and adding the underscores seems to have fixed the problem. Yay!

    I could swear that I tried removing the comments and conditionals from the default WP .htaccess and still had problems, but that might just be me being crazy. :p

    Thanks again! 😀

  4. Joseph says…

    Hi there,

    Just wondering if you could shed some light. When I installed WordPress on my Windows server, a .htaccess file was not created (unless I can’t see it), and I was wondering if you could share with me where it should go? And is the following code all I need to place it in?

    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule .* /index.php [L]

    Also, once created, does the server or IIS require a reboot?

    Great plug-in!

    Thanks, Joseph.

  5. andy says…

    @joseph this plugin requires IIS 6 and ISAPI Rewrite 3.0, as this version supports .htaccess files and the rewrite directives included here.

    There should now be a sample .htaccess file in the plugin download from the WordPress plugin repository.

    If you need help with an ISAPI Rewrite installation, be sure to hit up the good folks at Helicon.

    Let me know how this helped!

  6. andy says…

    @joseph and thanks for the kind words!

  7. JD says…

    It would be nice if you could expand this post and mention what setting to select when logged in as admin on wordpress i.e the permalinks section

  8. andy says…

    @JD The beauty is this allows you to use any of WordPress’ default permalink settings or your own custom setting.

    IIS, ISAPI Rewrite, the .htaccess file, and this plugin will make all URL’s that aren’t existing files or directories redirect to WordPress’ main controller script.

  9. Joseph says…

    Hi Andy,

    Sorry, I still don’t understand where to put the .htaccess file?

    Does it go somewhere in the WordPress installation folder? Or does it go in the root of the website? Or somewhere else?

    Much appreciated.


  10. andy says…

    @Joseph The .htaccess file needs to be in the installation directory of WordPress.

    If you have WordPress installed in C:\Inetpub\wwwroot\\ then the location of the .htaccess file would be C:\Inetpub\wwwroot\\.htaccess

    Again, make sure you hit up the ISAPI Rewrite Support Forums for more detailed support with their product.

  11. Joseph says…

    Hello Andy,

    Here are the steps I took to install your plug-in, unfortunately I still can’t get it going.

    1. Installed ISAPI Rewrite 3 Lite version (for now). I did not make any changes, simply accepted the defaults from the .msi

    2. Created a .htaccess file as you described, and placed it in the same directory as the WordPress index.php file (which is one directory above the other WordPress folders/files)

    3. Installed / Activated your plug-in

    4. Changed my permalinks to custom structure as follows; /%postname%/

    When I hover over a post title it shows the correct URL, but when I click the post, I get “The system cannot find the file specified.”

    Any thoughts?

    Thanks, Joseph.

  12. andy says…

    Joseph, sounds like an issue with ISAPI Rewrite 3. I’d make sure you’ve got it installed and handling .htaccess properly. I would contact their support to ensure that’s functioning properly. It sounds like WordPress is doing it’s job.

    You can add the following PHP snippet to a page template:

    <?php var_dump($_SERVER); ?>

    and make sure that the URL is present in $_SERVER[‘REQUEST_URI’], if it is, then the plugin is working as well.

  13. Joseph says…


    I don’t think this will not work with the lite version of ISAPI Rewrite 3. I installed the demo of the full version, and everything is good.

    I actually found a comment about this on

    You should edit the top of your post 😉


  14. andy says…


    I have a working Windows Server 2008 installation using IIS 6.0, WordPress 2.7, and ISAPI Rewrite 3 (Lite). See this screen shot:

    Using ISAPI Rewrite 3, Lite

  15. Joseph says…

    Hi Andy,

    Strange thing… when I had the lite version installed, the only way to see the right panel (that shows the .htaccess contents) was to highlight the top node, i.e. IIS Web Sites.

    When I highlighted one of the individual websites, the entire ISAPI Rewrite 3 screen went gray with a single message (something about doesn’t support… or not defined… I don’t remember).

    Then when I installed the full version, and highlighted any website in the tree, the right panel was available, and it displayed the contents of .htaccess (if it found one).

    Is it possible the lite version only supports 1 site?

    Great plug-in btw, nice and clean, and does the job!

    Thanks, Joseph.

  16. andy says…

    Nailed it! The Lite version does only support 1 site. That explains the disconnect. If you’re going to implement this setup, I’d recommend getting the full version, definitely worth it.

    Thanks for the compliments, hope it helps you out!

  17. Kerry says…


    Wonder if you could offer me some advice. I added Helicon Isapi 3 to my /blog/ subdirectory, edited the httpd.conf file (assume this is the equivalent to htaccess) file to to add the rules you stated above.

    I then activated your plugin and tried changing permalinks and my entire blog 404s. Not sure whya s your solution sounds a great alternative to fiddling with code!

    To be honest, also tried to do this the manual way by adding rules

    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule (.*) index.php?p=$1 [NC,L]

    and then adding

    if (isset($_SERVER[‘HTTP_X_REWRITE_URL’]))

    to the index.php file in the /blog/ subdirectory and then within httpdocs/blog/wp-content/themes/freshnews (freshnews being my theme) . When I add it at this level /blog/ the index page works and all posts 404. Also the code entered into the index.php seems to be pulled into my header, distorting my stylesheets.

    When I add it at theme level nothing happens. Although I’m yet to try to add to index.php in /wp-content/ and/or /themes/

    Seriously, do you have any idea what my problem could be with your tool? I’m going crazy! 🙂 I’m also posting my question re the manual code change issue on the Helicon forum, but thought you may have some ideas there.

    Anyway, any advice appreciated!

  18. Ash says…

    Ok so i have installed this plugin successfully on the root of a site and on a subdomain of another site using the following .htaccess in the root of the site/subdomain:

    # BEGIN WordPress

    Options +Followsymlinks
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]

    CheckSpelling On

    # END WordPress

    and the following permalink:


    But now i’ve moved the blog to and it doesn’t work at all.

    I’ve tried creating a new site on the same hosting (all of the above mentioned sites are hosted on the same reseller hosting cp – windows) and again setting the blog up in the /blog subfolder, with htaccess in that subfolder (i’ve even copied and pasted the exact same one from your example above) and it doesn’t work – file not found.

    Why would it work prefectly on the root of 4 or 5 sites but not in a subfolder?

    Great plugin, any help is greatly appreciated

  19. andy says…

    I don’t have any tests within a subdirectory, but I would try updating the RewriteBase directive to be:

    RewriteBase /path-name/

    Right now it’s assuming the root is the base directory. Give that a try and let me know, but currently this has only been successful for me in a root directory scenario.

  20. Ash says…

    Wow thanks for the amazingly fast reply!

    I figured it was the .htaccess but i dont know too much about them. I tried what you suggested and it didnt work, But then i figured i’d try the line at the bottom and it did work:

    RewriteRule . /blog/index.php [L]

    So for anyone who installs their blog in a subdirectory that should patch it up.

    Cheers once again Andy, you’re a star :0)

  21. andy says…

    @Ash Thanks, I’m glad you got it working. Ha, if I were a true star I would’ve caught the RewriteRule as well ;p

  22. Junaid says…

    Nice work on this, I am surprised this plugin is not more popular considering how many WordPress installations would be hosted on Windows.

    Please keep it maintained and up to date. It seems to work well on Windows 2008/IIS7 and WordPress 2.9 – so you could probably update the compatibility version list.

    Thanks and good job.

  23. andy says…

    @Junaid thanks! I’m not sure if it’s needed on IIS 7 as I think it has rewriting capabilities, it was mainly built for IIS 6 and ISAPI Rewrite when I had to work in that environment and the support was limited to editing core WP files.

    Good call on updating the stats, thanks for letting me know it’s working on Windows 2008 + IIS 7 as well as WP 2.9. I figured newer versions were supporting (and my workload has been full) so I haven’t had a chance to setup a new virtual environment to test the new versions.

    Thanks again for the kind words and I’m glad it helped you out!

  24. Chris says…


    I’m trying to get this working for a blog in a subdirectory (/blog), but I cant get it working properly. I’ve got it so the links are working fine, but however the CSS files are all broken, and then the admin pages dont work also.

    I’ve used Isapi Rewrite 3 successfully on a number of sites, so this is definitely working correctly.

    One possible problem is that the main site also has a .htaccess file, but this has rules to exlude blog. Could this be causing an issue? I’ve followed all the steps above.



  25. andy says…

    @Chris you might want to try putting the rules in the root directory’s .htaccess file. See the comment(s) by @Ash above.

    Also, try playing with the RewriteBase directive as well. If your site is working but CSS isn’t then it’s trying to rewrite the CSS URLs; I’d check to ensure you can see the CSS source when hitting them directly, and if not, the rewrite conditions ensuring the REQUEST_FILENAME property is not an actual file/directory may not be working, this could also be an issue with it being a nested .htaccess

  26. apar says…

    any one can help? how to write .htaccess in iis server to hiding file extension name

  27. andy says…

    I’m not 100% sure what you’re asking here, but if you’re having trouble creating the hidden file, I’d Google showing hidden file types in your version of Windows, then create a file named htaccess.txt in Notepad and rename it in Windows Explorer or launch the command line, cd to the file’s directory and run rename htaccess.txt .htaccess

  28. Brian Hunt says…

    Hi Andy,

    My host installed ISAPI Rewrite 4 on my domain yesterday but their instructions are these undecipherable C-code instructions for the .ini file.

    When you say to put the .htaccess file in the WP root, is that in the httpdocs folder? I ask because I don’t have write access to the next level up.

    Once I have the .htaccess file in place, then I also need to install the WP ISAPI Rewriter plugin in WP as well?

    Thanks for all your help with everyone’s questions on this.

  29. Brian Hunt says…


    I actually found out from my host that they’re running IIRF instead of Isapi Rewriter. I used your directives above in the INI file for IIRF and got the rewriting to work except that it still has the annoying “index.php” in the address. I note there is a directive above that notes “index.php.” Is there a directive that turns this off in the URL?

  30. apar says…

    andy, exactly i am talking about, I want to hide my file extension in web server such as, from to

  31. apar says…

    //heightlighted function
    class highlight
    public $output_text; //my 483 line is here

    function __construct($text, $words)
    $split_words = explode( " " , $words );
    foreach ($split_words as $word)
    $text = preg_replace("|($word)|Ui" ,
    "$1” , $text );
    $this->output_text = $text;

    hi andy this is my highlight function of php, I am using PHP 5.2.6 Version, but i am getting trouble like this

    Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or ‘}’ in C:\Inetpub\vhosts\\httpdocs\shopping\shopping.php on line 483

    please help me?

  32. Tom Johnson says…

    I have a client who has ISAPI Rewrite 2 and can’t upgrade to 3 because he already has a ton of rewrite rules for another site. I have the WordPress blog installed in a /blog subdirectory. Do you know if there’s a way to make the method you described work with ISAPI 2? Or is it possible to install ISAPI 3 in a subdirectory to work alongside ISAPI 2? Thanks for your help,


  33. andy says…

    @apar Sorry, I this thread is for the plugin, not PHP troubleshooting. As for a custom rewrite rule to make .php files have no extension, try:

    RewriteRule ^nepal/?$ nepal.php [L]

    You can use that and duplicate that rule for pages on your site. For more info on mod_rewrite checkout

  34. andy says…

    @Tom ISAPI Rewrite 3 supports the file and directory flags in the RewriteCond directives, but version 2 does not. That’s where the issue comes in.

    When I was stuck using version 2 (I avoid IIS all together now, btw), we wrote one rule for each page on the site, with the rules for sub-pages before the root page. Then we wrote a pattern for the blog URLs:

    # Pages
    RewriteRule ^about/news/?$ /index.php?p=4 [L]
    RewriteRule ^about/?$ /index.php?p=3

    # Posts
    # ----
    # assumes permalinks like /2010/03/postname/ID
    RewriteRule ^\d{4}/\d{2}/[^/]+)/(\d+)/?$ index.php?p=$1 [L]

    These are crude examples but should give you a starting point.

    Bottom line, hacking IIS to perform the awesomeness of mod_rewrite is a pain in the ass ;]

  35. Mauricio says…

    Hi Andy. Nice idea for a plugin!


  36. Mauricio says…

    I’ve been trying many methods but still get “The system cannot find the file specified. ”
    I have contacted my host service: they use Isapi Rewrite 3 on Windows 2003. I installed your plugin and tried many versions to .htaccess file.
    What should I do?

    Thank you very much in advance!

  37. Andy Schmidt says…

    Although the blog says that ISAPI Rewrite V2 won’t work, we are using these rules with success:


    # Don’t rewrite anything that ends with a filename.filetype, and optional query string
    RewriteRule (.*/[^/?]+\.\w+(?:\?.*)?)$ $1 [I,L]

    # For unknown reasons, categories require a REDIRECT
    RewriteRule ^/(category/.*) /index.php/$1 [I,L,RP]

    # If not already .php/… or .php?… then inject /index.php/
    RewriteCond URL ^(?:(?!\.php/|\.php\?).)*$
    RewriteRule /(.*) /index.php/$1 [I,L]

  38. Ryan says…

    I just wanted to thank you for this plugin. It saved my sanity when trying to migrate a clients wordpress site from linux to windows.

  39. andy says…

    Sorry for the long delay folks.

    @Andy Thanks for sharing that!

    @Ryan no prob. Glad it helped. Making WordPress and IIS 6 play nice was a pain in my ass for years.

    @apar let’s stay focused to the plugin in these comments.

    @Amy send me an email through the site if you’re still struggling.

    @Mauricio I honestly haven’t work on Windows Server since the initial development/testing of this plugin – which is easily a year now – I’m not sure what that’s about!

  40. apar says…

    Andy what are the reason to taking too long process to execute programing language and how would i solve permanently………

    i am using to transfer webpage text into database with php .

  41. Brian V. Hunt says…


    I have been struggling with WP and permalinks for two months. I had had to have my host install IsapiRewrite4 and I had to edit that file with a new rule everytime I added a page or post.

    I recently created some drop-down menus in Thesis and they would not work correctly under the rewrite solution I was using.

    I finally dumped the rewrite rules from the IsapiRewite4.ini, turned off the rewrite engine in that file, activated your plugin, and created an .htaccess file in the root.

    Voila, all rewrites are now working.



  42. Brian V. Hunt says…

    And I gave you props here:

  43. Neo says…

    Got it to work on Windows 2003 on IIS 6.0.

    Her we go:

    1. Install ISAPI Rewrite 3 Lite, just as it is described above.
    2. Put this on the C:\Program Files\Helicon\ISAPI_Rewrite3\http.conf file:

    # BEGIN WordPress

    Options +Followsymlinks
    RewriteEngine On
    RewriteBase /yoursubdirectoryname/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . index.php [L]

    CheckSpelling On

    # END WordPress

    Restart IIS only you’re just installed ISAPI Rewrite. You dont nedd to restart IIS each time you modified this file.

    3. DO NOT install the plugin. You dont need it.
    4. Enjoy

  44. andy says…

    @Neo – Thanks for posting. That’s awesome, if the headers in the latest version of ISAPI Rewrite are sending REQUEST_URI then you’re correct this plugin is a waste of time, and will probably break your site if they removed the X_HTTP_REWRITE header.

  45. dsv210 says…

    is there any way of getting wordpress permalinks to work without upgrading to isapi 3?
    we have our wordpress blog installed within our root folder on a windows 2003 server using iis6 and isapi 2.11 – we have around 30 websites on the server all using isapi 2.11 for rewrites – upgrading will be really difficult – as all the rules would need to be changed – is there any possible way around this?

  46. andy says…

    @dsv210 I’m not sure, I’m not familiar with your specific install and I avoid Windows hosting for anything PHP related like the plague.

    You can achieve the same effect but would need to write some generic rules so you’re not killing your CSS files or image files.

    That’s the main issue, ISAPI Rewrite 3.0 supports the -f and -d flags to ignore actual files and directories and only redirect URLs that don’t physically exist on the server.

    You could do something like:

    RewriteRule !\.(css|jpe?g|gif|png|js|pdf)$ index.php [L]

    Where you’ve got that subexpression representing all file names you could have static and just make sure you keep your permalinks extensionless.

    Hope that insight helps you out, good luck!

    P.S. Best solution is get WP off that host ;]

  47. dsv210 says…

    thanks for your suggestion andy – i will run this past my developer

  48. DDF Zone Diaries – Wordpress Pretty Permalinks – Windows IIS 5.1 « DDFZONE says…

    […] We downloaded and installed following Kyle Caufields post: Permalink for WordPress – IIS 6 mod_rewrite FIXED – Free . On Windows XP Pro, IIS  is accessed under Computer Management . The Default install location for ISAPI Remote is the Local Directory. We installed the ISAPI_Rewrite3  Filter under the Default Web Directory. If you plan on supporting multiple Web Sites, you will need  the Full Version. Hit up the  ISAPI Rewrite Support Forums  for more detailed support . But we still had 404 errors. We tried every configuration option we could find, and almost gave up since almost every solution was based on Windows Server 2003 and IIS 6 and none on our current system: – OS Version:  Windows XP Pro SP 3 – Server Version:  Microsoft-IIS/5.1 – MySQL Version:  5.0.17 – PHP Version:  5.2.5 – WordPress Version:  3.0 So, it would be natural to assume that you must run on a server platform for this to work. NOT GIVING UP ! . After more hours, articles and posts we discovered Andy Stratton’s plugin for WP   that not only handles the rewrites for our top-level pages but also the child pages under the drop down menus. Get WordPress Permalinks Working with Windows, IIS, and ISAPI Rewrite […]

  49. Richard Jones says…

    FYI, because I spent two days figuring this out:

    If you installed ISAPI_Rewrite from the installer package, you should not be manually adding an ISAPI filter to any of your sites, despite what instructions at other places on the Internet tell you.

    Doing so will cause problems because the installer package already installs a global ISAPI filter for you. Adding another ISAPI filter on top of this causes the filter rules to run twice, which is not good.

    See this link for verification from Helicon Tech:

    Hope this helps some people.

  50. Jay Greasley says…

    Hi Andy,

    I just wondered if you have tried this using Helicon Ape instead of/as well as ISAPIRewrite installed on the server?



RSS feed for comments on this post. TrackBack URL

Leave a Comment

April 28, 2009

Filed in Plugins, Wordpress

There are 65 comments »

« Back to the Blog