Using BlazorStatic from scratch
This guide will show you how to create static site using BlazorStatic. It is good for understanding how it works, but you can also use the BlazorStaticMinimalBlog where everything is already set up for you.
Create Blazor app
Start by creating new Blazor project.
Interactivityis set toNonesince that is not something we need for static site.dotnet new blazor --name BlazorStaticMinimalBlog --output BlazorStaticMinimalBlog --interactivity None --emptyRemove
blazor.web.jsfromApp.razor(we don't need it for static site).Make necessary changes to your layout. I am using tailwindcss, so everything is accommodated to that.
When you run
dotnet watchyour app should be running.(if you are also using tailwind, you need to run
tailwindcss -i .\wwwroot\app.css -o .\wwwroot\app.min.css -wor npm command )
Add content
Add you markdown files following this structure:
├───Content └───Blog │ first-post.md │ second-post.md └───media programming_bug.jpgThe directory structure can be customized (by
BlazorStaticOptions), but for simplicity we will use the default one.The post start with yaml front matter metadata.
--- title: First post lead: Sample post so you can see how it works published: 2024-06-20 tags: [tag-001, another-sample-tag] authors: - name: "Jan TesaÅ™" gitHubUserName: "tesar-tech" xUserName: "tesar_tech" ---These metadata has to match C# class (
BlazorStatic.BlogFrontMatter) that we will use now. You can use your own class, but it has to implementIFrontMatterinterface. You can also use multipleIFrontMatterclasses in one web app, see projects for more info (and its usage inProgram.cs).Mark Content folder to copy to the output:
<ItemGroup> <None Update="Content/**/*"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> </ItemGroup>You can also use
dotnet publishto copy the content folder to the output.
BlazorStatic nuget
dotnet add package BlazorStatic --prerelease
Turn on
StaticWebAssets. This will ensure wwwroot and RLCs assets are copied to the output folder.builder.WebHost.UseStaticWebAssets();Register services in
Program.csbuilder.Services.AddBlazorStaticService(opt => { opt.IgnoredPathsOnContentCopy.Add("app.css");//pre-build version for tailwind } ).AddBlazorStaticContentService<BlogFrontMatter>();BlogFrontMatteris the class that will be used to parse the metadata from markdown files. This is part of the BlazorStatic package. It exactly matches the metadata infirst-post.mdandsecond-post.md. Nothing stops you from creating your own class that will match your own metadata. It just needs to implement interfaceIFrontMatter, which has just one propertyList<string> Tags { get; set; }.As you can see
BlazorStaticServicehas options you can change. For example you can change the directory structure ( where your md files are located), or you can ignore some files (likeapp.cssin this case (we haveapp.min.css)).Use
BlazorStaticBefore running the app we need to tell the service to actually do something:app.UseBlazorStaticGenerator(shutdownApp: !app.Environment.IsDevelopment());UseBlazorStaticGeneratorwill parse the markdown files and expose them to the app as Postthrough BlazorStaticContentServiceand will generate the static files a put them into theoutputfolder (also customizable). It will shut down the app outside of development environment. This is meant for CI/CD pipelines, otherwise the app would run "forever" in particular job.
Scaffold the UI for blog posts
When you run the app right now, it will output the non-parametrized pages (e.g. @page "/" into index.html) and will
copy content of wwwroot into the output. You can set where to look for non-parametrized pages by
opt.RazorPagesPaths (default is Components/Pages folder).
File generation is done by using
HttpClientand saving the result into.htmlfile.
We need to scaffold the UI for blog posts. BlazorStatic doesn't force you to use any particular UI, but it will help you
by providing BlazorStaticContentService<BlogFrontMatter>.Posts collection where your processed posts live.
You get get some inspiration for th UI. These pages are important:
Blog.razor page which either displays the list of posts or the post itself. It starts with these page directives:
@page "/blog" @page "/blog/{fileName}"First will display the list of posts, second will display the post itself. The list of post is in
PostList.razorcomponent.PostsList.razor component, which is used in Blog.razor and Tags.razor pages to display the list of posts.
Tags.razor page, which either displays the tags cloud or the list of posts with particular tag. It have these page directives:
@page "/tags" @page "/tags/{tagName}"
For posts and tags generation, the directives must match the options, default value are:
builder.Services.AddBlazorStaticContentService<BlogFrontMatter>(opt => {
opt.PageUrl = "blog";
opt.TagsPageUrl = "tags";
});
Run and see
Now, when you run the app it outputs the static website into the output folder. When you open them the links and
images will not work. But it is fine. For debugging purposes you just run the app and don't care about the output. You
can even suppress the output by opt.SuppressFileGeneration = true; (default is false) and turn it on only for CI/CD
pipeline.
