Out of the box Sitecore way of handling 404 error is to respond with 302 redirect the original request to "sitecore/service/notfound.aspx". Then "sitecore/service/notfound.aspx" will respond with 404 response code.
It is not a good way for SEO purposes as crawlers think the page exists. It did not know it is a 404 response.
Sitecore provides a configuration setting not to redirect on an item not found.
<setting name="RequestErrors.UseServerSideRedirect">
<patch:attribute name="value">true</patch:attribute>
</setting>
Changing RequestErrors.UseServerSideRedirect to true will not redirect but with the response with 404 status code.
This helps in some way, but not completely, as in Sitecore we want 404 page to be content manage.
So, on the page not found
There is a configuration setting in Sitecore to set 404 content pages in Sitecore:
<setting name="ItemNotFoundUrl">
<patch:attribute name="value">/404</patch:attribute>
</setting>
<setting name="LinkItemNotFoundUrl">
<patch:attribute name="value">/404</patch:attribute>
</setting>
We can set the name of 404 content page here.
Here is how we can achieve this:
Add code to your patch file
<pipelines>
<httpRequestBegin>
<processor type="sitecoreBlog.tools4geeks.SitecoreCustom.Pipelines.HttpRequest.NotFoundProcessor, sitecoreBlog.tools4geeks.SitecoreCustom"
patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel']" />
</httpRequestBegin>
</pipelines>
public class NotFoundProcessor : Sitecore.Pipelines.HttpRequest.HttpRequestProcessor
{
public override void Process(Sitecore.Pipelines.HttpRequest.HttpRequestArgs args)
{
if (Sitecore.Context.Item != null || Sitecore.Context.Site == null || Sitecore.Context.Database == null)
{
return;
}
if (Sitecore.Context.Item == null)
{
var notFoundItem =
Sitecore.Context.Database.GetItem(string.Concat(Sitecore.Context.Site.StartPath,
Settings.ItemNotFoundUrl));
if (notFoundItem != null)
{
CustomContext.Current.PageNotFound = true;
Sitecore.Context.Item = notFoundItem;
}
}
}
}
Inherit your NotFoundProcessor from HttpRequestProcessor and override the process method.
I have created a singleton class called CustomContext to store values on every HTTP request, where I have stored current context request is PageNotFound.
Add this to your patch file:
<pipelines>
<httpRequestEnd>
<processor type="sitecoreBlog.tools4geeks.SitecoreCustom.Pipelines.HttpRequest.SetHttpResponseCode, sitecoreBlog.tools4geeks.SitecoreCustom"
patch:after="processor[@type='Sitecore.Pipelines.HttpRequest.EndDiagnostics, Sitecore.Kernel']"/>
</httpRequestEnd>
</pipelines>
public class SetHttpResponseCode : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
if (CustomContext.Current.PageNotFound)
{
HttpContext.Current.Response.StatusCode = (int) HttpStatusCode.NotFound;
}
}
}
Here we are checking the value we set on HttpRequestBegin Pipeline CustomContext.Current.PageNotFound based on it we are setting response status code to 404.
Let me know if you have any questions. Hope this helps.