A custom 404 page in Blazor Web Apps

4/14/2025
2 minute read

Sometimes you want to have a custom 404 page - and since .NET 8 and "Blazor WebApps" the <NotFound> tag of the Router doesn't work anymore, so let's create a custom page for that.

Before Blazor Web App (aka Blazor Server and Client)

In "earlier" times you could do the following inside your Router component:

<Router AppAssembly="@typeof(Program).Assembly">
	<Found Context="routeData">
		<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
	</Found>
	<NotFound>
		<LayoutView Layout="@typeof(MainLayout)">
			<p>Here your custom component or code that is shown when the navigation results in a 404</p>
		</LayoutView>
	</NotFound>
</Router>

That still works in the "old" approach where you either the client-side or server-side approach (aka something like <script src="_framework/blazor.server.js"></script>). But in the new Web App model that doesn't work. Still, you are able to pass in a NotFound child to the Router but it doesn't get picked up. The underlying Router type is different in the Web App (where you have <script src="_framework/blazor.web.js"></script> somewhere in your App.razor and have AddInteractiveServerComponents in your sevice container).

Adding a "fall trough" page

But we can easily define a web-page that is displayed with a lower specificity so that it has the least priority. Let's call that NotFoundPage.razor:

@page "/{*route:nonfile}"

<p>Here your custom component or code that is shown when the navigation results in a 404</p>
@code {
  [Parameter]
  public string? Route { get; set; }
}

The Route isn't used but mandatory - otherwise Blazor will throw an exception that it can not set route to a property. On my companies website https://bitspire.ch we did exactly that. Head over to: https://bitspire.ch/not-found (or add any useless subpage that probably doesn't exist) and you are greeted with a custom 404 page.

An error has occurred. This application may no longer respond until reloaded. Reload x