Search code examples
blazorblazor-webassembly

Dynamic page route parts in Blazor WASM app


In my Blazor app I want to have default pages such as:

/Home
/Info

With specific typical functionality.

However, I also want to have dynamic pages (perhaps generated from database content that will change over the lifetime of the app). These will also ideally be accessed by a single word, such as:

/Custom1
/Custom2

How can I use page routing so that code decides if the route is one of the valid dynamic pages (such as the Custom pages) whilst also retaining use of the default (static) pages?


Solution

  • The solution I found was to modify my App.razor to include the DynamicRouteHandler component to handle NotFound, i.e.

    <UserSettingsComponent>
        <Router AppAssembly="@typeof(App).Assembly">
            <Found Context="routeData">
                <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
                <FocusOnNavigate RouteData="@routeData" Selector="h1" />
            </Found>
            <NotFound>
                <DynamicRouteHandler/>
            </NotFound>
        </Router>
    </UserSettingsComponent>
    

    This means I can re-use my existing static pages and add dynamic capabilities without having to build a custom router.

    Then, with this in place I built the DynamicRouteHandler component as follows:

    @inject NavigationManager Navigation
    
    @if (IsDynamicPage)
    {
        @DynamicContent
    }
    else
    {
        <p>Loading...</p>
    }
    
    @code {
        public bool IsDynamicPage { get; set; }
    
        public RenderFragment DynamicContent { get; set; }
    
        [Inject]
        public NavigationManager NavigationManager { get; set; }
    
        protected override async Task OnInitializedAsync()
        {
            var location = NavigationManager.ToBaseRelativePath(NavigationManager.Uri);
    
            IsDynamicPage = true;
    
            if (IsDynamicPage)
            {
                SetupDynamicContent (location);
            }
            else
            {
                Navigation.NavigateTo("/404");  
            }
        }
    

    Note, SetupDynamicContent builds a RenderFragment with RenderTreeBuilder to dynamically create the page needed.