Making a Blog with C# - Part 7

Blogpost Navigation


Currently navigating between posts is cumbersome, so I wanted to add easy navigation.

To do this, I made a BlogPostNavigation component and added it to my BlogPostComponent

All my blog posts are currently stored in-code, so it's luckily very easy to determine whether there's a next/previous post in the series:

BlogPostNavigation.razor

<div class="mt-5">
<BlogPostNavigationButton BlogPost="_previousBlogPost"
                          BlogPostSeries="BlogPostSeries"
                          Next="false" />

<BlogPostNavigationButton BlogPost="_nextBlogPost"
                          BlogPostSeries="BlogPostSeries"
                          Next="true" />
</div>
@code {
    [Parameter]
    public BlogPostSeries BlogPostSeries { get; set; } = null!;

    [Parameter]
    public BlogPost CurrentBlogPost { get; set; } = null!;

    BlogPost? _previousBlogPost;
    BlogPost? _nextBlogPost;

    protected override void OnInitialized()
    {
        if (CurrentBlogPost.NumberInSeries > 1)
        {
            _previousBlogPost = BlogPostSeries
                .BlogPosts
                .FirstOrDefault(bp => bp.NumberInSeries == CurrentBlogPost.NumberInSeries - 1);
        }

        _nextBlogPost = BlogPostSeries
            .BlogPosts
            .FirstOrDefault(bp => bp.NumberInSeries == CurrentBlogPost.NumberInSeries + 1);
    }
}

The next and previous blog posts are determined based on the current blog post's number in it's series +/-1

They're then passed to the BlogPostNavigationButton component which renders them nicely, or returns early if they're null.

BlogPostNavigationButton.razor

@inject NavigationManager NavigationManager

@if (BlogPost is null)
{
    return;
}

<MudButton Color="Color.Primary"
           OnClick="@NavigateToBlogPost"
           Variant="Variant.Filled"
           StartIcon="@(Next ? string.Empty : Icons.Material.Filled.NavigateBefore)"
           EndIcon="@(Next ? Icons.Material.Filled.NavigateNext : string.Empty)"
           Size="Size.Small">
    @(Next ? $"Next: {BlogPost.Title}" : $"Previous: {BlogPost.Title}")
</MudButton>

@code {
    [Parameter]
    public BlogPost? BlogPost { get; set; } = null!;

    [Parameter]
    public BlogPostSeries BlogPostSeries { get; set; } = null!;

    [Parameter]
    public bool Next { get; set; }

    private void NavigateToBlogPost()
        => NavigationManager.NavigateTo(
            uri: BlogPostSeries.GetRelativePath(BlogPost!),
            forceLoad: true);
}

The BlogPostNavigationButton handles navigating to the previous/next blog post using the built-in NavigationManager. It's important to set forceLoad to true, because otherwise the markdown isn't reconstructed correctly.

Tying it all together in BlogPostComponent.razor

<BlogPostNavigation CurrentBlogPost="BlogPost" BlogPostSeries="BlogPostSeries"/>

And that's it!

Here's what the end product looks like:

Blogpost Navigation

Summary

We've added simple navigation buttons to move between blog posts, to make for a nicer reading experience.

See the code

Pull Request implementing the changes in this post

The state of the blog

State of the blog

An error has occurred. This app may no longer respond until reloaded. Reload 🗙