Should I put my Blazor components in the server project, or the client project?
Spin up a new .NET 8 Blazor project using the new web app template and you’ll find yourself looking at a number of projects.
Specifically, if you enable Auto
or WebAssembly
mode for your interactive components you’ll find yourself staring at two projects:
- YourApp
- YourApp.Client
But what are they, and where should you put your components?
NB: In the rest of this article we’ll refer to that first project (YourApp) as the main project for the solution.
Server-side rendered by default
Typically your .NET 8 Blazor components are going to start life as server-side rendered components.
This makes them work in a similar way to Razor pages, or MVC Views.
Someone visits a page on your site, their browser makes a GET request to your app running on the server.
ASP.NET forwards that request to the relevant Razor component, renders it, then returns the resulting HTML back to the browser.
The key thing to note here is that all of this is happening on the server.
So components being rendered this way can happily exist in your main project (YourApp), which will only ever run on your nice fast server.
Interactive but still on the server
But what if you want your components to be “more interactive”?
Static server-side rendering is great for pages which have minimal user interaction, where you can stick to using forms to capture data.
But if you want users to click elements, and your code to handle those clicks, you’ll need your component to run interactively.
One option here is to run them interactively on the server.
<MyComponent @rendermode="@InteractiveServer" />
Here your component will run via Blazor Server.
DOM Interactions will be forwarded to your app via a socket connection.
ASP.NET (on the server) ensures the relevant component instance handles those interactions, re-renders your component, and sends a ‘diff’ back to the browser (via the socket connection).
At this point Blazor running in the browser updates the DOM with the changes.
Again though, in this case, everything is running on the server, so your components are still good to sit in the main project for your app.
Interactive in the browser
Which brings us, finally, to Blazor’s two remaining render modes.
If you choose to render your component using InteractiveWebAssembly
or InteractiveAuto
your components are going to run interactively in the browser, via Web Assembly.
With InteractiveWebAssembly
your component will always render via Web Assembly.
With InteractiveAuto
it will try to use Web Assembly but fall back to using Blazor Server if WASM is unavailable, and/or can’t load quickly enough.
<MyComponent @rendermode="@InteractiveAuto" />
Crucially, with these render modes your components need to be shipped to the browser, where they will be rendered via WASM.
Now you generally don’t want your entire app to be sent to the browser.
Your .Server app has lots of code which can’t run in the browser, including code for directly accessing the database, making direct calls to your business logic etc.
It may also expose sensitive details, like database connection strings.
For these reasons, the .Server project must never find itself being bundled up and sent to the user’s browser.
But your InteractiveAuto
and InteractiveWebAssembly
components do need to be shipped to the browser.
Which is where the .Client project comes in.
By putting your components in .Client they can still run on the server (because the main project has a reference to the .Client project) plus they can be rendered in the browser if needed.
In Summary
If your components have any chance of being rendered in the browser, via either InteractiveWebAssembly
or InteractiveAuto
render modes, then they need to be located in the .Client project for your Blazor .NET 8 web app.
Otherwise, you can keep them in the main project and be sure they will never render directly in the browser.