Skip to content

Commit fc969ab

Browse files
committed
Updates
1 parent 5911969 commit fc969ab

File tree

2 files changed

+77
-216
lines changed

2 files changed

+77
-216
lines changed

aspnetcore/blazor/fundamentals/navigation.md

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ description: Learn about navigation in Blazor, including how to use the Navigati
55
monikerRange: '>= aspnetcore-3.1'
66
ms.author: wpickett
77
ms.custom: mvc
8-
ms.date: 09/23/2025
8+
ms.date: 09/24/2025
99
uid: blazor/fundamentals/navigation
1010
---
1111
# ASP.NET Core Blazor navigation
@@ -198,41 +198,30 @@ The following component:
198198
199199
`Navigate.razor`:
200200
201-
:::moniker range=">= aspnetcore-9.0"
202-
203-
:::code language="razor" source="~/../blazor-samples/9.0/BlazorSample_BlazorWebApp/Components/Pages/Navigate.razor":::
204-
205-
:::moniker-end
206-
207-
:::moniker range=">= aspnetcore-8.0 < aspnetcore-9.0"
208-
209-
:::code language="razor" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Components/Pages/Navigate.razor":::
210-
211-
:::moniker-end
212-
213-
:::moniker range=">= aspnetcore-7.0 < aspnetcore-8.0"
214-
215-
:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/routing/Navigate.razor":::
216-
217-
:::moniker-end
218-
219-
:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
220-
221-
:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/routing/Navigate.razor":::
222-
223-
:::moniker-end
201+
```razor
202+
@page "/navigate"
203+
@implements IDisposable
204+
@inject ILogger<Navigate> Logger
205+
@inject NavigationManager Navigation
224206
225-
:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
207+
<h1>Navigate Example</h1>
226208
227-
:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Pages/routing/Navigate.razor":::
209+
<button class="btn btn-primary" @onclick="NavigateToCounterComponent">
210+
Navigate to the Counter component
211+
</button>
228212
229-
:::moniker-end
213+
@code {
214+
private void NavigateToCounterComponent() => Navigation.NavigateTo("counter");
230215
231-
:::moniker range="< aspnetcore-5.0"
216+
protected override void OnInitialized() =>
217+
Navigation.LocationChanged += HandleLocationChanged;
232218
233-
:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Pages/routing/Navigate.razor":::
219+
private void HandleLocationChanged(object? sender, LocationChangedEventArgs e) =>
220+
Logger.LogInformation("URL of new location: {Location}", e.Location);
234221
235-
:::moniker-end
222+
public void Dispose() => Navigation.LocationChanged -= HandleLocationChanged;
223+
}
224+
```
236225
237226
For more information on component disposal, see <xref:blazor/components/component-disposal>.
238227

aspnetcore/blazor/fundamentals/routing.md

Lines changed: 58 additions & 186 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,32 @@
11
---
22
title: ASP.NET Core Blazor routing
33
author: guardrex
4-
description: Learn about Blazor app request routing.
4+
description: Learn about Blazor app request routing with guidance on static versus interactive routing, endpoint routing integration, navigation events, and route templates and constraints for Razor components.
55
monikerRange: '>= aspnetcore-3.1'
66
ms.author: wpickett
77
ms.custom: mvc
8-
ms.date: 09/23/2025
8+
ms.date: 09/24/2025
99
uid: blazor/fundamentals/routing
1010
---
1111
# ASP.NET Core Blazor routing
1212

1313
[!INCLUDE[](~/includes/not-latest-version.md)]
1414

15-
This article explains Blazor app request routing, including Static versus interactive routing, ASP.NET Core endpoint routing integration,
15+
This article explains Blazor app request routing with guidance on static versus interactive routing, ASP.NET Core endpoint routing integration, navigation events, and route templates and constraints for Razor components.
1616

1717
Routing in Blazor is achieved by providing a route template to each accessible component in the app with an [`@page`](xref:mvc/views/razor#page) directive. When a Razor file with an `@page` directive is compiled, the generated class is given a <xref:Microsoft.AspNetCore.Mvc.RouteAttribute> specifying the route template. At runtime, the router searches for component classes with a <xref:Microsoft.AspNetCore.Mvc.RouteAttribute> and renders whichever component has a route template that matches the requested URL.
1818

1919
The following `HelloWorld` component uses a route template of `/hello-world`, and the rendered webpage for the component is reached at the relative URL `/hello-world`.
2020

2121
`HelloWorld.razor`:
2222

23-
:::moniker range=">= aspnetcore-9.0"
24-
25-
:::code language="razor" source="~/../blazor-samples/9.0/BlazorSample_BlazorWebApp/Components/Pages/HelloWorld.razor":::
26-
27-
:::moniker-end
28-
29-
:::moniker range=">= aspnetcore-8.0 < aspnetcore-9.0"
30-
31-
:::code language="razor" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Components/Pages/HelloWorld.razor":::
32-
33-
:::moniker-end
34-
35-
:::moniker range=">= aspnetcore-7.0 < aspnetcore-8.0"
36-
37-
:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/index/HelloWorld.razor":::
38-
39-
:::moniker-end
40-
41-
:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
42-
43-
:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/index/HelloWorld.razor":::
44-
45-
:::moniker-end
46-
47-
:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
48-
49-
:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Pages/index/HelloWorld.razor":::
50-
51-
:::moniker-end
52-
53-
:::moniker range="< aspnetcore-5.0"
54-
55-
:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Pages/index/HelloWorld.razor":::
23+
```razor
24+
@page "/hello-world"
5625
57-
:::moniker-end
26+
<h1>Hello World!</h1>
27+
```
5828

59-
The preceding component loads in the browser at `/hello-world` regardless of whether or not you add the component to the app's UI navigation.
29+
The preceding component loads in the browser at `/hello-world` regardless of whether or not you add the component to the app's UI navigation as a link.
6030

6131
:::moniker range=">= aspnetcore-8.0"
6232

@@ -146,41 +116,17 @@ Components support multiple route templates using multiple [`@page` directives](
146116

147117
`BlazorRoute.razor`:
148118

149-
:::moniker range=">= aspnetcore-9.0"
150-
151-
:::code language="razor" source="~/../blazor-samples/9.0/BlazorSample_BlazorWebApp/Components/Pages/BlazorRoute.razor":::
152-
153-
:::moniker-end
154-
155-
:::moniker range=">= aspnetcore-8.0 < aspnetcore-9.0"
156-
157-
:::code language="razor" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Components/Pages/BlazorRoute.razor":::
158-
159-
:::moniker-end
160-
161-
:::moniker range=">= aspnetcore-7.0 < aspnetcore-8.0"
162-
163-
:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/routing/BlazorRoute.razor":::
164-
165-
:::moniker-end
166-
167-
:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
168-
169-
:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/routing/BlazorRoute.razor":::
170-
171-
:::moniker-end
172-
173-
:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
174-
175-
:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Pages/routing/BlazorRoute.razor":::
176-
177-
:::moniker-end
178-
179-
:::moniker range="< aspnetcore-5.0"
119+
```razor
120+
@page "/blazor-route"
121+
@page "/different-blazor-route"
180122
181-
:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Pages/routing/BlazorRoute.razor":::
123+
<h1>Routing Example</h1>
182124
183-
:::moniker-end
125+
<p>
126+
This page is reached at either <code>/blazor-route</code> or
127+
<code>/different-blazor-route</code>.
128+
</p>
129+
```
184130

185131
> [!IMPORTANT]
186132
> For URLs to resolve correctly, the app must include a `<base>` tag ([location of `<head>` content](xref:blazor/project-structure#location-of-head-and-body-content)) with the app base path specified in the `href` attribute. For more information, see <xref:blazor/host-and-deploy/app-base-path>.
@@ -360,41 +306,18 @@ The router uses route parameters to populate the corresponding [component parame
360306

361307
`RouteParameter1.razor`:
362308

363-
:::moniker range=">= aspnetcore-9.0"
364-
365-
:::code language="razor" source="~/../blazor-samples/9.0/BlazorSample_BlazorWebApp/Components/Pages/RouteParameter1.razor":::
366-
367-
:::moniker-end
368-
369-
:::moniker range=">= aspnetcore-8.0 < aspnetcore-9.0"
370-
371-
:::code language="razor" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Components/Pages/RouteParameter1.razor":::
372-
373-
:::moniker-end
374-
375-
:::moniker range=">= aspnetcore-7.0 < aspnetcore-8.0"
376-
377-
:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/routing/RouteParameter1.razor":::
378-
379-
:::moniker-end
380-
381-
:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
382-
383-
:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/routing/RouteParameter1.razor":::
384-
385-
:::moniker-end
386-
387-
:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
309+
```razor
310+
@page "/route-parameter-1/{text}"
388311
389-
:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Pages/routing/RouteParameter1.razor":::
312+
<h1>Route Parameter Example 1</h1>
390313
391-
:::moniker-end
392-
393-
:::moniker range="< aspnetcore-5.0"
314+
<p>Blazor is @Text!</p>
394315
395-
:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Pages/routing/RouteParameter1.razor":::
396-
397-
:::moniker-end
316+
@code {
317+
[Parameter]
318+
public string? Text { get; set; }
319+
}
320+
```
398321

399322
:::moniker range=">= aspnetcore-5.0"
400323

@@ -410,41 +333,20 @@ Optional parameters aren't supported. In the following example, two [`@page` dir
410333

411334
`RouteParameter2.razor`:
412335

413-
:::moniker range=">= aspnetcore-9.0"
414-
415-
:::code language="razor" source="~/../blazor-samples/9.0/BlazorSample_BlazorWebApp/Components/Pages/RouteParameter2.razor":::
416-
417-
:::moniker-end
418-
419-
:::moniker range=">= aspnetcore-8.0 < aspnetcore-9.0"
420-
421-
:::code language="razor" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Components/Pages/RouteParameter2.razor":::
422-
423-
:::moniker-end
424-
425-
:::moniker range=">= aspnetcore-7.0 < aspnetcore-8.0"
426-
427-
:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/routing/RouteParameter2.razor":::
428-
429-
:::moniker-end
430-
431-
:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
432-
433-
:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/routing/RouteParameter2.razor":::
434-
435-
:::moniker-end
436-
437-
:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
438-
439-
:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Pages/routing/RouteParameter2.razor":::
336+
```razor
337+
@page "/route-parameter-2/{text?}"
440338
441-
:::moniker-end
339+
<h1>Route Parameter Example 2</h1>
442340
443-
:::moniker range="< aspnetcore-5.0"
341+
<p>Blazor is @Text!</p>
444342
445-
:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_WebAssembly/Pages/routing/RouteParameter2.razor":::
343+
@code {
344+
[Parameter]
345+
public string? Text { get; set; }
446346
447-
:::moniker-end
347+
protected override void OnParametersSet() => Text = Text ?? "fantastic";
348+
}
349+
```
448350

449351
When the [`OnInitialized{Async}` lifecycle method](xref:blazor/components/lifecycle#component-initialization-oninitializedasync) is used instead of the [`OnParametersSet{Async}` lifecycle method](xref:blazor/components/lifecycle#after-parameters-are-set-onparameterssetasync), the default assignment of the `Text` property to `fantastic` doesn't occur if the user navigates within the same component. For example, this situation arises when the user navigates from `/route-parameter-2/amazing` to `/route-parameter-2`. As the component instance persists and accepts new parameters, the `OnInitialized` method isn't invoked again.
450352

@@ -469,8 +371,6 @@ In the following example, the route to the `User` component only matches if:
469371
```razor
470372
@page "/user/{Id:int}"
471373
472-
<PageTitle>User</PageTitle>
473-
474374
<h1>User Example</h1>
475375
476376
<p>User Id: @Id</p>
@@ -568,29 +468,18 @@ Consider the following `Example` component that can receive a route parameter fr
568468

569469
`Example.razor`:
570470

571-
:::moniker-end
572-
573-
:::moniker range=">= aspnetcore-7.0 < aspnetcore-8.0"
574-
575-
:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_Server/Pages/routing/Example.razor":::
576-
577-
:::moniker-end
578-
579-
:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
580-
581-
:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_Server/Pages/routing/Example.razor":::
582-
583-
:::moniker-end
584-
585-
:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
586-
587-
:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_Server/Pages/routing/Example.razor":::
588-
589-
:::moniker-end
471+
```razor
472+
@page "/example/{param?}"
590473
591-
:::moniker range="< aspnetcore-5.0"
474+
<p>
475+
Param: @Param
476+
</p>
592477
593-
:::code language="razor" source="~/../blazor-samples/3.1/BlazorSample_Server/Pages/routing/Example.razor":::
478+
@code {
479+
[Parameter]
480+
public string? Param { get; set; }
481+
}
482+
```
594483

595484
:::moniker-end
596485

@@ -648,39 +537,22 @@ Catch-all route parameters are:
648537

649538
`CatchAll.razor`:
650539

651-
:::moniker-end
652-
653-
:::moniker range=">= aspnetcore-9.0"
654-
655-
:::code language="razor" source="~/../blazor-samples/9.0/BlazorSample_BlazorWebApp/Components/Pages/Catchall.razor":::
656-
657-
:::moniker-end
658-
659-
:::moniker range=">= aspnetcore-8.0 < aspnetcore-9.0"
660-
661-
:::code language="razor" source="~/../blazor-samples/8.0/BlazorSample_BlazorWebApp/Components/Pages/Catchall.razor":::
662-
663-
:::moniker-end
664-
665-
:::moniker range=">= aspnetcore-7.0 < aspnetcore-8.0"
666-
667-
:::code language="razor" source="~/../blazor-samples/7.0/BlazorSample_WebAssembly/Pages/routing/CatchAll.razor":::
668-
669-
:::moniker-end
670-
671-
:::moniker range=">= aspnetcore-6.0 < aspnetcore-7.0"
540+
```razor
541+
@page "/catch-all/{*pageRoute}"
672542
673-
:::code language="razor" source="~/../blazor-samples/6.0/BlazorSample_WebAssembly/Pages/routing/CatchAll.razor":::
543+
<h1>Catch All Parameters Example</h1>
674544
675-
:::moniker-end
676-
677-
:::moniker range=">= aspnetcore-5.0 < aspnetcore-6.0"
545+
<p>Add some URI segments to the route and request the page again.</p>
678546
679-
:::code language="razor" source="~/../blazor-samples/5.0/BlazorSample_WebAssembly/Pages/routing/CatchAll.razor":::
680-
681-
:::moniker-end
547+
<p>
548+
PageRoute: @PageRoute
549+
</p>
682550
683-
:::moniker range=">= aspnetcore-5.0"
551+
@code {
552+
[Parameter]
553+
public string? PageRoute { get; set; }
554+
}
555+
```
684556

685557
For the URL `/catch-all/this/is/a/test` with a route template of `/catch-all/{*pageRoute}`, the value of `PageRoute` is set to `this/is/a/test`.
686558

0 commit comments

Comments
 (0)