TLDR; Azure Static Web Apps is a service that allows you to deploy both JavaScript apps but now also Blazor apps. The service is simple to use as it only requires an Azure subscription and a GitHub repo. That's all the set up you need.
Resources
- Blazor on Static Web Apps blog post
- Blazor LEARN Module
- Blazor + Static Web Apps Tutorial
- Blazor + Static Web Apps, LEARN module
- Intro to Blazor
- Working with Blazor and JavaScript
Blazor
Blazor is a framework that allows you to write C# fullstack. If you are developing a fullstack web application, you usually have to involve JavaScript at some point. You either add it to improve the interaction of your pages or you split between having a backend in .NET and the frontend in JavaScript using for example a SPA framework like React, Angular or maybe Vue. A Blazor app can be compiled into WebAssembly and can thereby be a first-class web citizen and also really fast.
If you are completely new to Blazor I recommend reading this intro article.
What is Azure Static Web apps service
Static Web Apps is an Azure service with which you can deploy fullstack apps within minutes. It can deploy both JavaScript projects as well as Blazor.
NET developer here, you have my attention. So, it can deploy a Blazor project, what else can it do?
- Web hosting, your app is hosted on Azure, the end product it hosts is just HTML, CSS and JavaScript or Web Assembly.
- Integrated API, you can add a Serverless API to your app at any time.
- Free SSL certificates
- Reverse proxy. When calling APIs, no need to configure CORS, it just works.
- Social auth + AAD supported. Through simple configuration get auth providers like GitHub, Linked In and even Azure Active Directory authentication/authorization to just work. This includes being able to set up separate roles to have access to specific resources.
That's a nice featurelist. I care about ease of use, what can you tell me about that?
There's not much to fill in, everything revolves around your GitHub repo and once you selected a repo, and a few other things, it starts deploying it.
Ok, but how does it work under the hood?
It works by creating and running GitHub actions that carries out things like fetching dependent libraries, building your code, and finally deploying it. You end up getting a so-called workflow file pushed to your repo (it's a YAML file).
Alright, but I'm likely to update my code quite a lot, does it help me with redeploy?
It does, you can define in the workflow file when a redeploy should be trigger, like merging of a PR or a commit to master/main branch for example.
This all sounds very promising; can you take me through a deploy?
Of course, next thing on my list :)
Deploy your first Blazor app
- Clone an app. The easiest way to get started is to create a Blazor app from this GitHub template
Generate app
from GH template. Ensure you are logged into GitHub before clicking this link or you will get a 404
Once it's done generating you now have a repo on your GH user. Type the following command:
git clone <name of repo URL>
-
Inspect an app. To inspect the app, first ensure you have the latest version of dotnet core installed install. Change directory to that of your cloned repo.
- Build the solution. Ensure you are standing at the solution root and type the following command:
dotnet build
- Run the client app. Run the client by typing the following command:
cd Client
dotnet run
You should get a terminal output similar to the following:
info: Microsoft.Hosting.Lifetime[0]
Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path:
/path/to/project/blazor-sample/Client
- Navigate to the app. Type the following URL in the browser localhost:5000. The browser should now display the following content:
Deploy the app
At this point you have a working Blazor app that you can deploy using Azure Static functions. How do you do that?
- Navigate to the URL portal.azure.com in your browser and log on to Azure.
- Type Static Web Apps and select the suggestion.
- Click the + Add in the top left area.
Now you are met with a set of dropdowns where you need to fill in some info.
- Subscription, select the subscription you want
- Resource group, select the resource group you want or create a new one.
- Name. Give the app name.
- Region. Select a region.
- SKU. No need to do a selection here, the service is free for now.
- Click Sign in to GitHub, after clicking this button you will need to locate and pick your generated repo.
- Organization. Select organization.
- Repository. Select the repo that was created when you generated it from the template.
- Branch.. Select the branch, in this case we only have the main branch.
-
Build presets. Select Custom, now you are presented with some options:
- App location. This is where the client app lives, so type /Client here.
- Api location, leave as default
- App artifact location. This is the folder that your client app gets built to. Give it the following value wwwroot
- Click Review + Create.
- Click Create at this point if you are happy with all selections you've made.
Click to be taken to the resource once deployed. The resource page should look something like this:
Above you have the resource. You could click the URL from the indicated field, but it would take you to default page. Why is that? Your app hasn't finished building yet. Instead click the link GitHub action runs. This will take you to the GitHub actions of your repo. Once all the actions have finished it should look like so:
- Revisit your app. Now go back to the resource page at the Azure portal and click that app URL. You should see the following:
There you have it, your deployed app :)
Adding an API
Now a Blazor app could contain its own backend. The way the Azure Static Web Apps service is constructed though it assumes your backend will be located in an Api directory. So what should be in that directory? Well a function app. Luckily your repo already have a working function app, almost.
Let's review our repo quickly. Your solution should look something like this.
-| Api
-| Data
-| Client
You already know about the Client directory where your Blazor app lives. The other directory of interest is the Api directory that contains a Function app. It's an almost functioning Function app. What do I mean by almost? Well let's have a look at it, expanding the Api directory there are some files of interest:
Client/
Api/
ProductData.cs
ProductsDelete.cs
ProductsPost.cs
ProductsPut.cs
The first file ProductData.cs
contains an in-memory data store. The remaining three files is just routes for our API.
*** Adding missing GET route
For this API to be a full Create Read Update Delete it needs another file ProductsGet.cs
, let's create that file and give it the following content:
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
namespace Api
{
public class ProductsGet
{
private readonly IProductData productData;
public ProductsGet(IProductData productData)
{
this.productData = productData;
}
[FunctionName("ProductsGet")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "products")] HttpRequest req)
{
var products = await productData.GetProducts();
return new OkObjectResult(products);
}
}
}
Now select Run > Start debugging from the top menu in VS Code. At the end of the build output you should have text stating something like this:
ProductsPut: [PUT] http://localhost:7071/api/products
ProductsGet: [GET] http://localhost:7071/api/products
ProductsPost: [POST] http://localhost:7071/api/products
ProductsDelete: [DELETE] http://localhost:7071/api/products/{productId:int}
You are almost there.
Testing locally, set up CORS
When testing things out locally you need to instruct the Function to allow requests from a cross domain, i.e our Blazor app. How do we do that? Locate the local.settings.json file and ensure it has the following content:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
},
"Host": {
"CORS": "*"
}
}
Above you added the Host property and made CORS point to allowing all requests. This is just something we do locally, don't worry about this making production.
At this point you can run your client Blazor app and it will look like this:
The Blazor app is now able to talk to your Function app backend.
Deploy the app, now with API
So how do you deploy this so that the API part is there? You need to do the following:
- Adjust the workflow YML file and point out the Api directory
- Push the changes you did you did to the workflow file and Api directory
That's it, the way the workflow file is constructed it should pick up the changes on push and redeploy the app.
Adjust workflow file
Open up the workflow file. It's a file ending in .yml in your .github sub directory (ensure you have done a git pull before this so you get this file as it's created and added to your repo the first time you deploy).
Locate the section called
api_location:
. Ensure it looks like this api_location: "/Api". This will point out our Api sub directory.
Push the changes
Type the following command:
git add .
git commit -m "adding API"
git push
The above should push your changes to GitHub and the GitHub actions should be triggered.
- Go to the GitHub actions tab and wait for the actions to finish. Now ensure you reload the page
You should now see something like this:
There you have it, both your Blazor client and your API is working. !
Summary
You've been taken through
- Generating a Blazor fullstack app from a GitHub template
- You've first deployed the Blazor app
- Secondly you added an API to your Blazor app and ensured it worked locally before proceeding.
- Lastly, you added the API by pushing a commit and the app was redeployed
Conclusion, Azure Static Web Apps service is a really fast way to deploy a Blazor app. If you are using Serverless the service takes care of that too.
What's next
There's more things to learn like fallback routes and how to secure your app. I urge you to look through the links in the references section, both to learn more about Blazor but also to take the LEARN module that goes through what we just did a bit slower. There's also some links how to add auth, support for AAD is built-in and needs only to be configured to work..
Hope this got you inspired to build lots of Blazor apps. :)
Top comments (8)
Hi Chris, this url: github.com/MicrosoftDocs/mslearn-s... returns a 404, is the GH repo public? I do see the other mslean-staticwebapp repo. Looking forward to play and learn with these cool new features.
Marc,
This has been resolved, the repo here is the associated Learn module that was being published. Please take some time and look at that as well! docs.microsoft.com/learn/modules/p...
Excellent! Thanks Shayne!
Nice 😄, Only use case to use
Blazor
is , if you want to create client side apps inC#
, Are there any other use cases ?A Blazor app can easily be fullstack.. it's an alternative to building a Web App on .NET. I mean you have full access to all the .NET libs...
So cool! You are a gifted writer too. Thank you for sharing.
appreciate that Christopher :)
Hi Chris, this is fanstastic post!
About the functions being deployed, how can I view the logs from their execution as I don't see them in Function app?