Implementing SEO Rule On Website Hosted on IIS8

In this post, we are going to optimize a website that is hosted on IIS8, by implementing basic SEO rules to help improve the user experience as well as to increase the SEO ranking.
 
We will optimize our IIS application according to Google’s Search Engine Optimization Starter Guide. Let’s get into it. First of all, we will get a basic overview of IIS8 and SEO.
 
IIS8: Microsoft’s Internet Information Server (IIS) is an extensible web server that hosts multiple web applications/sites.
 
IIS supports HTTP, HTTPS, FTP, FTPS, SMTP and NNTP protocols.
 
Other web servers include:
  1. Apache
  2. NGNIX (pronounced engine X) from NGNIX
  3. Novell’s NetWare Server
  4. Google Web Server (GWS)
  5. IBM’s family of Domino Servers
SEO: SEO (Search Engine Optimization) is a process of improving the visibility of a website in search engine results. Learn more from Google SEO guide
 
Table of Content
  1. Improving Site Structure
    • Sitemap
  2. Dealing with Crawlers
    • robot.txt
    • BOT accessibility(Libwww-perl Access)
  3. Server Security
    • Server Signature (Server: Microsoft-IIS/8.0)
  4. Canonicalization
    • URL Canonicalization
    • IP Canonicalization
  5. Optimizing Content
    • Page Cache (Server Side Caching)
    • Expires Tag
    • HTML Compression/GZIP
Let’s get the details about these topics with a basic sample application hosted in IIS. First of all, we need to configure the IIS in order to host our website. We will change Windows host file to set hostname with local IP and port.
 
Modification of Host file
Browse the file : c:\Windows\System32\Drivers\etc\hosts.
 
 
 
Hit enter or open it with notepad. Copy the following content to this file. You can copy its existing content to another opened note for future uses.
 
 
 
Now, open your browser. In address bar, write localseo.com and hit enter. Our local site will load.
 
Improving Site Structure
 
Sitemap
 
Applications need to be well structured based on the root/home page. It is better to use breadcrumbs that help users to navigate to root/home page. Sitemap improves the crawling of site by crawlers. We can also use a sitemap XML file to help web crawlers (Google or Other search engine) with listing the page content of the site.
 
Below is a sample sitemap XML format. Upload the XML file (sitemap.xml) to root folder. 
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <urlset  
  3.       xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"  
  4.       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.       xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9  
  6.       http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">  
  7.   
  8.   <url>  
  9.     <loc>http://localseo.com</loc>  
  10.   </url>  
  11.   <url>  
  12.     <loc>http://localseo.com/Home</loc>  
  13.   </url>  
  14.   <url>  
  15.     <loc>http://localseo.com/About</loc>  
  16.   </url>  
  17.   <url>  
  18.     <loc>http://localseo.com/Contact</loc>  
  19.   </url>  
  20. </urlset>  
In IIS, I have placed the sitemap.xml file in the root folder.
 
 
 
Dealing with Crawlers
 
Web Robots
 
Web robots, known as spider/crawler, are programmed to visit/index the site content automatically. Robots.txt file is used to give instructions to the web robots about the crawling of the website. There are two statements used: User-agent: * and Disallow. 
  1. The “User-agent: *” means this section applies to all robots.
  2. The “Disallow: /” tells the robot that it should not visit any pages on the site.
Learn more about robot.
 
Libwww-perl Access BOT
 
We can restrict BOT access using webconfig by URL rewrite rules. We need to enable IIS URL Rewrite 2.0. Click Web Platform Installer in the IIS Management section.
 
 
 
A list of components will appear. Search the “Rewrite” here. 
 
 
 
Search result will show URL Rewrite 2.0. Install it now.
 
 
After installation, the URL Rewrite icon will appear. Double click on it.
 
 
 
Let’s create a new rule for Libwww-perl BOT to restrict access website.
 
 
 
Then, configure for BOT rule to restrict.
 
 
 
Or simply copy paste below code in webconfig. Then, replace your pattern.
  1. <rule name="BOT request BLOCK" stopProcessing="true">  
  2.           <match url=".*" />  
  3.           <conditions>  
  4.             <add input="{HTTP_USER_AGENT}" pattern="^Libwww-perl$" />  
  5.           </conditions>  
  6.           <action type="CustomResponse" statusCode="403" statusReason="Forbidden: Access is denied." statusDescription="You do not have permission to view this directory or page using the credentials that you supplied." />  
  7. </rule>  
Server Security
 
Server Signature
 
From security aspects, it is important to turn it off. By default, it is set ON. Here, we will rewrite the server signature with outbound rule in IIS.
 
 
 
Again, double click on URL Rewrite icon and add Server variable, like in the following image.
 
 
 
 
 
 
 
or simply copy and paste the below code in webconfig and replace your changed values.
  1. <outboundRules>  
  2.         <rule name="Server Signature">  
  3.           <match serverVariable="RESPONSE_SERVER" pattern=".+" />  
  4.           <action type="Rewrite" value="Changed" />  
  5.         </rule>  
  6. </outboundRules>  
 
 
Canonicalization
 
URL Canonicalization
 
 
 
Make sure the bindings are proper with the host name in IIS. Now, create a new inbound rule for Canonicalization of both the IP and the URL, with www.
 
 
 
Or simply copy paste the below code in webconfig. Replace your values here and redirect.
  1. <rule name="Canonical HOST redirect">  
  2.           <match url="(.*)" />  
  3.           <conditions>  
  4.             <add input="{HTTP_HOST}" pattern="^www\.localseo\.com$" negate="true" />  
  5.           </conditions>  
  6.           <action type="Redirect" url="http://www.localseo.com/{R:1}" />  
  7. </rule>  
Optimizing Content
 
For better performance, it is good to cache the static content. There are three different cache Control Modes. The default is NoControl.
  1. NoControl - Does not add a Cache-Control or Expires header to the response.
  2. DisableCache - Adds a Cache-Control: no-cache header to the response.
  3. UseMaxAge - Adds a Cache-Control: max-age=<XXX> header to the response, based on the value specified in the CacheControlMaxAge attribute.
  4. UseExpires -  Adds an Expires: <DATE> header to the response, based on the date specified in the httpExpires attribute.
Page Cache (Server Side Caching) 
 
 
 
 
  1. <staticContent>  
  2.       <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />  
  3.  </staticContent>  
 
 
Expires Tag
  1. <staticContent>  
  2. <clientCache cacheControlMode="UseExpires" httpExpires="Wed, 01 Jan 2020 00:00:00 GMT" />  
  3. </staticContent>  
 
 
HTML Compression/GZIP
 
 
 
 
Finally, the web.config file.
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!--  
  3.   For more information on how to configure your ASP.NET application, please visit  
  4.   http://go.microsoft.com/fwlink/?LinkId=301880  
  5.   -->  
  6. <configuration>  
  7.   <appSettings>  
  8.     <add key="webpages:Version" value="3.0.0.0" />  
  9.     <add key="webpages:Enabled" value="false" />  
  10.     <add key="ClientValidationEnabled" value="true" />  
  11.     <add key="UnobtrusiveJavaScriptEnabled" value="true" />  
  12.   </appSettings>  
  13.   <system.web>  
  14.     <compilation targetFramework="4.5.2" />  
  15.     <httpRuntime targetFramework="4.5.2" />  
  16.   </system.web>  
  17.   <system.webServer>  
  18.     <staticContent>  
  19.       <clientCache cacheControlMode="UseExpires" httpExpires="Wed, 01 Jan 2020 00:00:00 GMT" />  
  20.     </staticContent>  
  21.     <!--<staticContent>  
  22.       <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />  
  23.     </staticContent>-->  
  24.     <rewrite>  
  25.       <rules>  
  26.         <rule name="Canonical HOST redirect">  
  27.           <match url="(.*)" />  
  28.           <conditions>  
  29.             <add input="{HTTP_HOST}" pattern="^www\.localseo\.com$" negate="true" />  
  30.           </conditions>  
  31.           <action type="Redirect" url="http://www.localseo.com/{R:1}" />  
  32.         </rule>  
  33.         <rule name="BOT request BLOCK" stopProcessing="true">  
  34.           <match url=".*" />  
  35.           <conditions>  
  36.             <add input="{HTTP_USER_AGENT}" pattern="^Libwww-perl$" />  
  37.           </conditions>  
  38.           <action type="CustomResponse" statusCode="403" statusReason="Forbidden: Access is denied." statusDescription="You do not have permission to view this directory or page using the credentials that you supplied." />  
  39.         </rule>  
  40.       </rules>  
  41.       <outboundRules>  
  42.         <rule name="Server Signature">  
  43.           <match serverVariable="RESPONSE_SERVER" pattern=".+" />  
  44.           <action type="Rewrite" value="Changed" />  
  45.         </rule>  
  46.       </outboundRules>  
  47.     </rewrite>  
  48.   </system.webServer>  
  49.   <runtime>  
  50.     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">  
  51.       <dependentAssembly>  
  52.         <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />  
  53.         <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />  
  54.       </dependentAssembly>  
  55.       <dependentAssembly>  
  56.         <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />  
  57.         <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />  
  58.       </dependentAssembly>  
  59.       <dependentAssembly>  
  60.         <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />  
  61.         <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />  
  62.       </dependentAssembly>  
  63.     </assemblyBinding>  
  64.   </runtime>  
  65.   <system.codedom>  
  66.     <compilers>  
  67.       <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />  
  68.       <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" />  
  69.     </compilers>  
  70.   </system.codedom>  
  71. </configuration>  
  72. <!--ProjectGuid: 7D096796-F3E8-4C10-BB3F-2BC4542846C6-->  
Hope this will help!