[Blazor, Router] Ability to set a base route for a page from a layout
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
### Is there an existing issue for this?
- [X] I have searched the existing issues
### Is your feature request related to a problem? Please describe the problem.
When having multiple pages with the same base route, e.g. `/project/{projectName}`, it can be annoying to ensure that all the project pages have the same base route, and if you decide to change the route to `/project/{projectId:guid}`, you have to go through all your pages and change them.
Another problem with today's solution is, let's say you want to localize your site and have the selected language shown in the uri for all the pages e.g. `/{lang}/...`, not only do you have you include it in all the route templates, but you need a way to validate it. Of course you can have every page use a common PageLayout that validates the language in the uri, but the only way to get a value from the uri is to use the NavigationManager and get the current uri. But then you have to split it and get the right segment, which might not be the most practical solution.
### Describe the solution you'd like
Now, a simple solution for this is to allow layouts (components that inherit LayoutComponentBase) to define a base route which will be prefixed to all pages (component that have at least one Page attribute defined) that uses the layout.
Example:
*ProjectLayout.razor*
```razor
@inherits LayoutComponentBase
@baseroute "/project/{projectId:guid}"
@Body
@code {
[Parameter]
public required Guid ProjectId { get; init; }
}
```
*ProjectSettings.razor*
```razor
@layout ProjectLayout
@page "/settings"
Settings
@code {
[CascadingParameter(Name = "ProjectId")]
private Guid projectId { get; set; }
}
```
Final ProjectSettings url: `/project/{projectId}/settings`
To define a base route, you have to use the `@baseroute` directive (something other than @page, this route should not be navigable from the browser).
If *ProjectLayout.razor* had another layout defined of e.g. `BaseLayout.razor`, which in turn had a base route of `@baseroute "/{lang}"`, then the final url for ProjectSettings would be `/{lang}/project/{projectId}/settings`, base routes can be chained.
### Cons
* Not really a problem, but more of a limitation. Base routes only work on pages that have a Layout attribute directly defined. The DefaultLayout in App.razor would be ignored if it has a *@baseroute* defined.
* It could become harder to find what the final url is for a page when part of the route is defined in another file. But because of the previous point described, you know that it comes from the layout and not some totally random file.
### Additional context
_No response_
Contributor guide
Research direction
Start by reading LayoutComponentBase and the existing @page handling for Blazor components. Define how a @baseroute on directly assigned layouts is combined, including chained layouts, and verify that the resulting URLs match the ProjectSettings examples while the base routes are not independently navigable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100