Allow the use of SEO-friendly URL structures by translating URLs to a series of querystring parameters, letting the underlying web application to operate, unchanged, as if these querystring parameters exist natively in the request uri.

Rewrite Simple URLs

Consider the following URL to a user’s profile page:

  • https://example.com/users/fred (with or without a final trailing slash /)

And this needs to be exposed to the web application as:

  • https://example.com/users.php?username=fred

Simply add the following to rule to the <rules> section of web.config:

<system.webServer>
    <rewrite>
        <rules>
            <rule name="Rewrite user url to param" stopProcessing="true">
                <match url="^users/(.*)/?$" />
                <conditions>
                    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                </conditions>
                <action type="Rewrite" url="users.php?username={R:1}" />
            </rule>
        </rules>
    </rewrite>
</system.webServer>

Rewrite Product Browsing URLs

Consider the following series of URLs, part of a product browsing scheme:

  • /products/
  • /products/mens/
  • /products/mens/clothing/
  • /products/mens/clothing/sportswear/
  • /products/mens/clothing/sportswear/sale/

This structure can be rewritten to expose the ‘directory’ strings as parameters to the actual browse routine. Add the following rule to .htaccess:

 <system.webServer>
    <rewrite>
        <rules>
            <rule name="Rewrite product urls to params" stopProcessing="true">
                <match url="^products/?([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?$" />
                <conditions>
                    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                </conditions>
                <action type="Rewrite" url="products.php?dept={R:1}&amp;cat={R:2}&amp;subcat={R:3}&amp;status={R:4}" />
            </rule>
        </rules>
    </rewrite>
</system.webServer>

This would cause requests to these URLs to be transparently rewritten to:

  • /products/
    • /products.php?dept=&cat=&subcat=&status=
  • /products/mens/
    • /products.php?dept=mens&cat=&subcat=&status=
  • /products/mens/clothing/
    • /products.php?dept=mens&cat=clothing&subcat=&status=
  • /products/mens/clothing/sportswear/
    • /products.php?dept=mens&cat=clothing&subcat=sportswear&status=
  • /products/mens/clothing/sportswear/sale/
    • /products.php?dept=mens&cat=clothing&subcat=sportswear&status=sale

Note that from the web application’s perspective, it will potentially see empty parameter values depending on the product url provided and what the ‘depth’ of the url actually is, so code should be written accordingly to check the length of string parameters or check for valid numeric values in a parameter which expects numbers before leveraging the values in code.