Sitecore 404 Page Not Found handler without 302

When your requested page not found and while handling 404 error page, are you getting 200 or 302 HTTP Status Error Code? Then there is something to do more to achieve 404. For SEO purpose, our 404 error page should return a 404 response header. By default Sitecore shows a Page Not Found page but it's not 404 in real.

There can be many approaches to achieve 404 in Sitecore depending on our requirement. Here, two of them are shown.
  1. Show a specific Sitecore page on 404.
    This will show 404-Page Not Found page with current language, device and layout requested. Means, if you request any page from mobile and desktop, both will show 404 but with different rendering/output set in both device/layouts.
  2. Simple 404 - Page Not Found text.
    This will simply show text with 404 status code.

1. Show a specific Sitecore page on 404.

Step - 1:

Create a new processor which will be used before ExecuteRequest in httpRequestBegin pipeline in web.config. If context item is null, then set an Sitecore Item (errorpage) as Context and set a flag in Request Cache that this request is of 404.
namespace SitecoreTactics.Pipelines.HttpRequest
{
    public class Page404Resolver : Sitecore.Pipelines.HttpRequest.HttpRequestProcessor
    {
        public override void Process(Sitecore.Pipelines.HttpRequest.HttpRequestArgs args)
        {
            // If current item not available in Sitecore, then
            if(Sitecore.Context.Item == null)
            {
                // Find an error-page item and set it to context Item
                Item item404 = Sitecore.Context.Database.GetItem("Path of error-page Item");
                Sitecore.Context.Item = item404;

                // Set a flag in request cache to say this request is of 404.
                Sitecore.Context.Items["is404"] = "true";
            }
        }
    }
}
//else, continue pipeline... So no need to write else block

Step - 2:

In web.config, do below settings in HttpRequestBegin pipeline.
Add above processor Page404Resolver below ItemResolver as below.
<httpRequestBegin>
  <-- few processors -->
  <processor type="Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel" />
  <processor type="SitecoreTaxtics.Pipelines.HttpRequest.Page404Resolver, SitecoreTactics.Pipelines" />
  <-- few processors -->
</httpRequestBegin>

Step - 3:

In layouts, check whether this request Cache has flag to true (means 404), then set the Status Code to 404 and description
Change in Layout:
protected override void Render(HtmlTextWriter writer)
{
    base.Render(writer);

    // If current request is for 404-errorpage...
    if (Sitecore.Context.Items["is404"] == "true")
    {
        try
        {
            Response.StatusCode = 404;
            Response.TrySkipIisCustomErrors = true;
            Response.StatusDescription = "File not found";
            Response.End();
        }
        catch (ThreadAbortException)
        {
             // Log error
        }
    }
}

2. Simple 404 - Page Not Found text

To just write down some 404 message, use above processor itself, but change code as below. In this approach, there is no need to write any code in layout as above.

// If current item not available in Sitecore, then go for 404
if (Sitecore.Context.Item == null)
{
  System.Web.HttpContext context = System.Web.HttpContext.Current;
  
  // Apply Response Headers
  context.Response.TrySkipIisCustomErrors = true;
  context.Response.StatusCode = 404;
  context.Response.StatusDescription = "Page not found";
  
  try
  {
    // Write 404 - description to response
    string str404 = "The page you requested does not exist.";
    context.Response.Write(str404);
    context.Response.End();
  }
  catch (System.Threading.ThreadAbortException ex)
  {
    // Log error
  }
}

That's it, you have your 404!!

No comments:

Post a Comment