Published on

Adding a seo friendly custom 404 page in ASP.NET Core

Authors

1) Wire it up in Program.cs (.NET 6+)

Place the status-code middleware before endpoint mapping:

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseRouting();

app.UseAuthorization();
app.UseStatusCodePagesWithReExecute("/error/not-found"); // <-------- here

app.MapStaticAssets();
app.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}")
    .WithStaticAssets();


app.Run();

Why WithReExecute?
It keeps the status code and re-runs the pipeline, so you can serve a view (not a redirect). This is better for SEO. Redirecting to a 404 page wil be seen as a redirect in the browser. Reexecute keeps the status code and url does not change. This is exactly what we want :)


2) Add an ErrorController

Create Controllers/ErrorController.cs:

using Microsoft.AspNetCore.Mvc;

public class ErrorController : Controller
{
    // You can expand this to handle other codes (404, 500, etc.)
    [Route("error/not-found")]
    public IActionResult NotFoundPage()
    {
        // Ensure correct status code
        Response.StatusCode = 404;
        return View("NotFound");
    }
}

3) Create the Razor View: Views/Error/NotFound.cshtml

@{
    ViewBag.Title = "title";
    Layout = "_Layout";
}

<section class="container">
    <h2>404 – Page Not Found</h2>
    <p>
        Sorry, we couldn’t find the page you were looking for.
    </p>

    <div>
        <a class="btn btn-primary" href="/" aria-label="Go to homepage">Go Home</a>
        <a class="btn btn-outline-secondary" href="javascript:history.back()" aria-label="Go back to previous page">Go Back</a>
    </div>
</section>

4) Try it out

Run the app and navigate to a path that does not exist. You should see your Razor-based 404 page and the browser should also receive the correct status code.


Why Razor Instead of a Static 404.html?

  • Branding & Layout: Reuse your site layout, styles, logo and general feel of the site.
  • Localization: Use existing files, ViewComponents and Partial Views. No need for a static html file.
  • Analytics: Existing implementation for analytics and telemetry can be used. Helpful for tracking 404 pages.
  • Extensibility: Show helpful links, content that could be related, search box etc. Example: A product page returns a 404, but we know the collection/category it lives under, due to the path in the url. Then we have the option to show list products in the same collection, for the user to navigate to.