Blazor WebAssembly, Server or Auto: which to choose in production in 2026?
The first load of Blazor WASM starts at 1.5-2 MB compressed for a simple app and can reach 5-8 MB: on 3G that means 12-25 seconds of waiting. Blazor Server has an immediate TTI but requires a permanent WebSocket connection per user and has horizontal scaling limits without additional configuration (sticky sessions or Redis).
Blazor Auto combines the best of both: first load from Server with ready-made HTML, then automatic transition to WASM once the runtime is downloaded in the background.
The pre-go-live checklist covers five critical areas: rendering mode, SEO and meta tags, performance, security and infrastructure. Getting one of these wrong in production costs months of remediation.

Taking Blazor into production looks like a formality.
It is not.
I have watched this play out dozens of times: the tech lead proposes Blazor WebAssembly for the company's new public portal.
The reasoning sounds solid.
The team already knows C#, nobody has to learn JavaScript, and models and domain logic are shared between front end and back end inside the same project.
Everyone in the meeting room nods.
The project starts, the tests pass, the release goes smoothly.
Six months later, the CEO asks why the application does not show up on Google.
Organic traffic is zero.
The first load takes eight seconds on mobile.
Every page shared on LinkedIn shows the same empty preview.
Only then does the tech lead discover what "client-side rendering" means to a search engine, and realise that no weekend patch is going to fix it.
Here is the heart of the matter: Blazor is an excellent technology, but under the bonnet it is three different technologies.
Four, if you count static rendering.
Each with its own architecture and its own trade-offs.
Picking the wrong mode produces no compiler errors.
It produces problems that detonate in production, months after release.
And by then fixing them is expensive: time, reputation, often revenue.
Far more expensive than choosing well would have been at the start.
This article covers everything that meeting should have put on the table before anyone opened Visual Studio.
The three rendering modes and how they really differ.
When each one makes sense, and when it is a mistake.
The SEO problem and how it is actually solved.
The real numbers on first load, authentication and where security genuinely lives, an honest comparison with React and Angular, and a practical checklist before launch.
The three Blazor rendering modes: they are not all the same

Blazor is not a single technology.
It is a family of rendering models that share Razor syntax and the C# language, but that work in completely different ways underneath.
And the consequences are concrete.
What changes is where the code lives, what the browser downloads, and how data travels between client and server.
Confusing them, or accepting the default mode without understanding what it implies, leads straight to the disaster described above.
From .NET 8 onwards, Blazor exposes four rendering modes, which you select per component with the @rendermode attribute.
- Static Server: no interactivity, HTML generated once.
- Interactive Server: what everyone still calls Blazor Server.
- Interactive WebAssembly: Blazor WASM.
- Interactive Auto: a combination of the previous two.
Per-component granularity is the real step change in .NET 8.
Previously the entire application had to commit to a single mode.
Today you mix them, page by page or component by component, according to what each part of the interface actually needs.
Blazor WebAssembly (WASM) runs .NET code directly in the browser.
No server generates HTML: the browser downloads the .NET runtime, the DLLs and all the logic, then runs everything on its own, without going back to the server to render.
It is a pure client-side model, structurally similar to React or Angular, but written entirely in C#.
Blazor Server, renamed Interactive Server in .NET 8, does the opposite.
Rendering happens on the server, the browser receives ready-made HTML, and communication runs over a SignalR connection on WebSocket.
Every click, every keystroke, every navigation travels along that connection to the server, which recalculates and sends back only the part of the page that changed.
Blazor Auto, introduced in .NET 8 and refined through .NET 9, combines the two in sequence.
On the first load it uses Server: HTML is ready immediately, and the user can interact without waiting for any download.
In parallel, the browser downloads the WebAssembly runtime in the background.
On later visits, once the download has completed, the components switch to WASM mode on their own and the rendering dependency on the server disappears.
Declaring a component's mode takes a single Razor directive at the top of the file, next to the route directive.
You specify Server, WebAssembly or Auto, and that is it.
The transition from Server to WebAssembly is handled by the framework, with no extra code to write, on one condition: the component has to work properly in both environments.
Keep that in mind, because it is a constraint we come back to later.
Alongside the three interactive modes there is static server-side rendering (Static SSR), designed for pages that need no interactivity: editorial content, information pages, marketing sections.
Static SSR generates HTML on request, without holding state on the server and without downloading any runtime to the client.
For the public part of a site it is often the most efficient choice, even when the rest of the application uses WASM or Server.
Mixing Static SSR, WASM, Server and Auto in the same application is not merely possible: most of the time it is the right approach.
You give each component the mode that best fits its own requirements for interactivity, SEO and performance.
This is not a matter of style.
This choice determines SEO, first-load speed, infrastructure requirements and offline behaviour for the entire application.
Teams that miss this find out once the application is already in users' hands, and at that point changing course means rewriting whole parts of the project.
One detail catches out developers coming from classic ASP.NET Core: a Static SSR component with interactive islands is rendered twice.
First the server generates the HTML; then the interactive component attaches itself to the DOM that is already there, the step the wider web calls hydration.
If initialisation has side effects, an API call that increments a counter for instance, that effect risks firing twice instead of once.
The fix is to distinguish explicitly between the prerendering phase and the interactive one, rather than assuming initialisation happens only once.
Blazor WebAssembly in production: when it makes sense and when it does not
Blazor WebAssembly is the mode most often chosen for the wrong reasons.
"This way we do not need a server for the front end", "it is like React but in C#", "we can work offline".
Technically correct observations, in the abstract.
Each one hides implications you need to understand before going into production, not after the phone call from an unhappy client.
When WASM is the right choice
For internal applications, business systems and company dashboards, where access is authenticated and SEO is irrelevant, WASM is almost always the best option if the team already knows .NET.
Here the initial download happens once per employee, the DLLs end up in cache, and from the second visit onwards everything runs locally with excellent performance.
An internal CRM, a warehouse management system, a reporting dashboard for the management team: in scenarios like these, a few seconds of waiting on first access, typically once a day, is a perfectly acceptable trade-off.
In exchange, the team writes everything in C#, without learning a second full stack.
For progressive web apps with genuine offline requirements, Blazor WASM with a service worker works without a connection and synchronises data once the network returns.
Think of field service engineers, on-site inspections, data collection on a construction site or anywhere the signal comes and goes: the technician fills in the form offline, and the app synchronises at the first bar of coverage.
For applications with complex client-side logic, where avoiding a server round-trip on every interaction improves the experience measurably, WASM is often the only sensible choice.
Think of a text or code editor, a calculator with elaborate formulas, tools that work on data already sitting on the client without querying the server on every keystroke.
When WASM is a textbook mistake
For any public application that lives on organic traffic, pure Blazor WASM is almost always the wrong choice.
A company blog, an information portal or an online shop built entirely in WASM will have structural SEO problems, and they only surface months after launch (we look at them shortly).
By the time you notice, going back and restructuring the public architecture costs weeks of work that an upfront analysis would have avoided.
When the first load decides whether a visitor converts, the bill is just as steep.
Before it becomes interactive, a WASM app has to download and run the entire .NET runtime in the browser: on a mid-range phone that is several seconds of waiting.
Google's figures are unforgiving: past three seconds of loading on mobile, more than half of users leave.
For a landing page, a lead capture form or a product page that is lost revenue, and the people who leave almost never come back to try again.
The real dividing line is a single one: authenticated internal context on one side, public context that lives on traffic on the other.
In the first, Blazor WASM is the best choice available.
In the second it becomes a production problem, with a direct impact on revenue rather than a footnote in a code review.
Choosing the right mode first time is not luck: it is craft.
People who know Blazor properly make these decisions inside a single meeting, not after six months of zero organic traffic.
That is exactly the craft you build in the Blazor course: architecture, real cases and the mistakes not to repeat, explained by someone who has already paid for them in production.
Blazor Server in production: SignalR, circuits and scaling limits
Blazor Server solves the first-load problem elegantly.
HTML rendered by the server, shown by the browser straight away, and SignalR handling all subsequent communication.
For SEO the pages are complete HTML from the very first response: they are indexed correctly, with no tricks required.
But there is a price, and it is structural.
Every connected user holds a WebSocket open to the server for the whole session, and the server has to keep the state of the circuit in memory for every active connection.
The circuit includes the rendered components, the state of any forms being filled in, and the DOM tree used to calculate differences.
With a hundred concurrent users you cope comfortably on modest infrastructure.
With ten thousand on the same machine, sizing becomes a serious problem.
The numbers for capacity planning
A server with 2 GB of RAM dedicated to a Blazor Server app handles roughly 5,000 to 15,000 concurrent circuits.
The range depends on the complexity of the application, how much state you hold per user and the type of interaction: an app with simple forms sustains more circuits than one with data grids refreshed in real time.
The numbers vary from project to project, but they give you the order of magnitude to start from.
Below a few thousand concurrent users, a single well-sized server is enough.
Above that threshold, have the infrastructure conversation before go-live, not after.
Horizontal scaling
To scale Blazor Server across several instances behind a load balancer you have two options:
- Sticky sessions: each user always lands on the same server for the whole session.
- A distributed SignalR backplane: it synchronises state across instances, typically Redis or Azure SignalR Service.
Without one of the two, a user routed to a server other than the one holding their circuit loses the session instantly.
In production this shows up as random and apparently inexplicable disconnections.
Azure SignalR Service moves the WebSocket connections off the application server: clients live on the managed service, and your application talks to that instead of to the browsers.
On Azure it is the simplest route if you would rather not run Redis yourself: you pay for one more dependency and a cost that grows with concurrent connections.
The disconnection risk
If the WebSocket drops, because of network instability, a timeout or a server restart, Blazor Server shows the reconnection message and tries to restore the circuit within the configured window.
But if the server has restarted in the meantime, the circuit is gone for good: the user reloads from scratch and throws away any unsaved data.
For long working sessions this scenario is something you design for, not something you endure.
The operator filling in a form for twenty minutes, the complex quotation configurator: the countermeasures are periodic automatic saves, visual confirmation that data has been persisted on the server, and a clear message when reconnection fails.
The alternative is that the user discovers the damage only when they hit submit.
Blazor Server is the right choice for internal applications, with a stable network and concurrent users in the low thousands.
For public portals with high traffic, unpredictable peaks and unreliable mobile connections, the infrastructure requirements soon become punishing, in cost and in operational complexity.
Blazor Auto in .NET 8 and 9: the hybrid mode that changes the picture

Auto mode, introduced in .NET 8, is Microsoft's answer to a long-standing dilemma: take the best of Server and WASM, and move the complexity of the transition into the framework instead of onto your shoulders.
The mechanism works like this.
On first access, interactive components run in Server mode: the page arrives already rendered and the user can work with it immediately.
In parallel, without blocking anything, the browser downloads the WebAssembly runtime and the DLLs.
When the download finishes, within a few seconds on fast connections, or already in place on later visits thanks to the cache, the components switch to WASM mode by themselves.
From that point on, and for every subsequent session, the application runs entirely locally, with no rendering dependency on the server.
What changes in practice
The first load is as immediate as in Blazor Server: no waiting for the WebAssembly bundle, no initial spinner (the animated loading indicator) to send users away.
From the second visit onwards, interactions are as fast as in a pure WASM app, all inside the browser.
Above all, the server no longer has to hold an active circuit for every connected user, which removes most of the scaling problem described in the previous section.
The constraints to consider
The biggest constraint, and the one that surprises teams during development, is that components have to work in both modes.
Services that depend on the browser (localStorage, geolocation, the Web Crypto API) are not there when the component runs on the server side.
And the reverse applies too: direct database access, the file system and configuration secrets do not exist when the component runs in WASM inside the browser.
The practical solution is to abstract these resources behind a common interface, shared across the project, with two separate implementations injected according to the environment.
One talks to the browser when there is one, the other uses a database table when the component runs on the server.
The Razor component always works against the interface, and has no idea which implementation is active at any given moment.
It demands more care in designing services from day one, but it saves you from rewriting half the application when the first incompatible service turns up.
Infrastructure is more complex than for a single mode as well.
You need both the Server logic for the first visit, with all its circuit management, and the distribution of the WASM bundle for subsequent visits, with the static asset hosting that goes with it.
In .NET 9 Auto mode has been refined, with improvements to WASM asset caching and to how smoothly the handover between the two modes happens.
The edge cases that in early .NET 8 versions caused small visible jumps during the Server to WASM transition are gone.
Today it is the most balanced choice for public applications that want both pre-rendered HTML for SEO and full client-side autonomy in later sessions.
It is the default I recommend when there are no specific constraints pushing towards pure WASM or pure Server.
For a broader comparison of web stack choices in .NET, see the article on ASP.NET Core and the other web frameworks.
SEO and Blazor WebAssembly: the real problem and how to fix it
The SEO problem with Blazor WebAssembly is not a bug to be fixed.
It is a direct consequence of the client-side architecture.
Google uses a Chromium-based crawler that can execute JavaScript and wait for a single-page application to render.
In the field, though, three concrete problems emerge, and they always appear months after launch.
Problem 1: delayed rendering
The crawler (the automated program search engines use to explore the web) arrives at the page and finds almost empty HTML, with a loading spinner.
It has to wait for the .NET runtime to load and render the page.
Google states that it waits for single-page applications, but the wait is limited and not guaranteed: beyond five or six seconds, the crawler indexes the empty page or skips it altogether.
In Google Search Console you see it like this: pages indexed with no title and no description, empty snippets (the preview of a page that appears in search results) that nobody notices until the organic traffic stops arriving.
Problem 2: crawl budget
Every site is explored with a limited budget, proportional to the authority of the domain, and pages that are heavy to render consume more of that budget per URL.
A site with hundreds of pages in pure Blazor WASM gets indexed incompletely: the less important pages are skipped, and new ones take weeks to appear in the index.
Meanwhile the marketing team wonders why the content they publish brings no traffic even after months.
Problem 3: dynamic meta tags for social sharing
Open Graph meta tags for sharing on LinkedIn, Facebook and similar platforms are often inserted by Blazor after loading.
But social crawlers do not execute JavaScript: they see only the static HTML of index.html, with generic or empty meta tags.
The result: every shared page shows the same preview, whatever the content.
It looks like a cosmetic detail, until you notice that clicks from social platforms are close to zero.
The practical solutions
The most robust solution is to let the server prepare the page, instead of leaving all the work to the browser.
In Blazor that means using Auto mode, or static rendering for public pages.
You can see the difference for yourself in thirty seconds.
Open the page, right click, "View source".
With pure WASM you find an empty shell: there is only the loading spinner, the content does not exist yet.
With a page prepared by the server you find the whole article, already written out.
Google receives exactly what you are reading there: in the first case it indexes emptiness, in the second it finds everything on the first pass.
Then do not take theory on trust: check.
Google Search Console has a tool, URL Inspection, that shows you the page exactly as Google really saw it.
Two minutes, and you know whether the problem is solved or not.
And if the project has to stay on pure Blazor WASM, because the decision and the investment are already made? Then split the site in two.
At the front, the pages that need to be found on Google: blog, product pages, landing pages.
Build those as ordinary pages, which Google reads without effort.
Behind the login, where Google does not go anyway, lives the real application in WASM.
The two parts exchange data and coexist perfectly well, each optimised for its own purpose.
There is a twin problem, which only surfaces when somebody analyses the site properly.
You know the review stars under a Google result, the product price, the frequently asked questions that open directly in the search page?
They come from a few lines of information hidden in the page, which Google reads and turns into those boxes.
In a pure WASM app those lines appear only after loading, when Google has already moved on: and the stars never arrive.
With a page prepared by the server they come out together with everything else, and Google always finds them.
If SEO is a requirement, pure Blazor WebAssembly is not the right mode. Blazor with SSR or Blazor Auto solve the problem at its root, while keeping C# across the whole stack.The SEO problem in Blazor can be solved, but only if you know where to intervene before writing the first line of code.
That is the difference between learning Blazor from tutorials and learning it in a structured way: the Blazor course starts precisely from the architecture of the rendering modes, so you win the organic traffic from the first release, not after the rewrite.
Blazor performance in production: initial download, TTI and optimisation
Blazor performance in production is measured on three things: the weight of the initial bundle, the Time to Interactive (TTI) and steady-state speed, after the first load.
Initial bundle size in Blazor WASM
A Blazor WASM production build, optimised with trimming and Brotli compression, starts at roughly 1.5 to 2 MB for a simple application.
With substantial dependencies, UI component libraries, cryptography or complex serialisation, you climb to 5 to 8 MB.
After the first download the DLLs stay in cache and subsequent visits fly, but the first access always costs, and every application update invalidates the cache.
From .NET 8, DLLs are packaged in the webcil format, a container that avoids the raw .dll extension in HTTP traffic.
Some corporate firewalls and older antivirus products used to block Blazor DLLs, mistaking them for suspicious executables; webcil removes that friction without you having to do anything.
For comparison: an optimised React production build starts at 100 to 300 KB for most applications.
The gap is structural: Blazor WASM carries a complete .NET runtime into the browser, React does not.
Time to Interactive on real connections
Times measured on typical connections tell the story better than any argument:
On 3G, at those speeds, most users have already gone.
And the low TTI of Blazor Server is paid for with the permanent WebSocket per user, described in the previous section:
| Scenario | Time to Interactive |
|---|---|
| Blazor WASM on broadband (50 Mbps) | 2 to 4 seconds |
| Blazor WASM on 4G (10 Mbps) | 4 to 8 seconds |
| Blazor WASM on 3G (1 Mbps) | 12 to 25 seconds |
| Blazor Server | 0.5 to 2 seconds |
Bundle optimisation strategies
Trimming with AOT (Ahead of Time) compilation in .NET 9 reduces the runtime by including only the code actually used, and compiles .NET code into native WebAssembly before release.
Runtime performance improves, because there is no JIT in the browser, but the initial bundle can grow a little, because native WASM code compresses less well than DLLs.
Evaluate it case by case: it is not a free improvement.
Lazy loading of modules loads parts of the application only when they are needed.
On apps with many separate features it cuts the initial download by 40 to 60%: what is rarely used is downloaded only when the moment comes.
Brotli compression, on the server or on the CDN, reduces transfer weight compared with gzip.
And static assets (DLLs, runtime) want a Cache-Control header with a long max-age, so they are not downloaded again on every visit.
For interfaces with long lists, the Virtualize component renders only the elements visible in the viewport, not the whole list.
It applies to both WASM and Server, and it is often more noticeable than any bundle optimisation.
From .NET 8, even Static SSR pages can behave like a single-page application when navigating and submitting forms, thanks to enhanced navigation and enhanced form handling.
The framework intercepts links and submissions, updates only the portion of the page that changed without a full refresh, and does so without downloading a single byte of WebAssembly runtime.
For many public applications, static HTML plus enhanced navigation covers the experience that used to require WASM or Server, without the weight or the complexity of either.
Measure instead of guessing
Every number in this section changes with the real project, so the rule is a single one: measure before optimising.
Chrome DevTools with the Lighthouse panel, in simulated 4G mode, gives a realistic estimate of the TTI an average user experiences.
For the WASM bundle, the size report from dotnet publish -c Release tells you which assemblies weigh most, and that is where you discover dependencies nobody remembered adding.
Steady-state performance
Once loaded, Blazor WASM is extremely fast for operations that stay inside the browser.
Blazor Server, by contrast, introduces a fixed latency on every interaction, equal to the WebSocket round-trip to the server: typically 10 to 50 ms on local connections, 50 to 200 ms on distant ones.
With real-time typing or drag and drop, the interface feels noticeably less responsive than WASM.
Try it with real users before dismissing it as negligible.
Authentication and security in Blazor: where protection actually lives

Authentication in Blazor has a few peculiarities that catch out anyone who has so far worked only with the traditional approach of the framework, especially in WebAssembly mode.
The fundamental rule is a single one: in Blazor WASM all client code is exposed to the user, and no secret can stay hidden in anything that runs in the browser.
Real protection always happens on the server side, in the API endpoints the application calls.
Those endpoints have to validate the token on every request, regardless of what the client claims to be.
That means the [Authorize] decorator on a Blazor WASM component is user experience only, not security: it hides or shows interface elements according to the authentication state the client declares.
A few minutes and the browser developer tools are enough to bypass any check of that kind.
A typical JWT flow in Blazor WASM
The complete token round-trip comes down to four steps:
- The user signs in from a login form that calls an ASP.NET Core endpoint.
- The server validates the credentials and returns a JWT.
- The client stores the token and puts it in the
Authorizationheader of every subsequent API call. - The server revalidates the token on every call, whatever the interface is showing.
LocalStorage versus HttpOnly cookies
Storing the JWT in localStorage is convenient and widespread, but it exposes the token to XSS attacks.
If an attacker injects malicious JavaScript into the page, they read the token from localStorage and use it for unauthorised API calls from outside, potentially long afterwards.
The safer route is HttpOnly cookies managed on the server side: JavaScript cannot read them, not even with a successful XSS.
You pay with a little more complexity in the back end and you take home a markedly better security profile.
For any application handling sensitive data, accept that trade.
Blazor Server and Identity
In Blazor Server, authentication looks more like classic ASP.NET Core: the server maintains the session, the user authenticates with a cookie, and every component accesses the identity through AuthenticationStateProvider.
Secrets stay on the server, a structural advantage over WASM that eliminates whole categories of risk from the outset.
For enterprise applications, integration with Entra ID, Identity Server or other OIDC providers is the standard choice.
The .NET 8 templates already include ready-made scaffolding for ASP.NET Core Identity with Blazor, which works well in both Server mode and Auto with prerendering.
Watch out for antiforgery tokens in forms too: recent templates handle them automatically, but check they are present in every form that writes data.
This applies in particular to projects migrated from earlier versions of .NET, where the scaffolding was not yet up to date.
When the API lives on a different domain
A common and underestimated scenario: the Blazor WASM front end served from a different domain than the APIs it consumes, for example app.example.com against api.example.com.
Here HttpOnly cookies need extra attention: the SameSite and Secure attributes have to be configured explicitly so the cookie travels on cross-origin requests.
And the CORS policy on the server side has to declare the exact origin of the front end, without wildcards that would undo the protection you have just built.
This is the classic point where "it works locally" stops working on the first release to separate environments: verify it before go-live, do not discover it alongside your client.
Security mistakes are unforgiving: you do not find them in a code review, you find them once somebody has already exploited them.
In the Blazor course, authentication, tokens and going into production are tackled the way you will tackle them at work: on a real project, with feedback on what you write.
Before go-live, not alongside your client.
Blazor versus React and Angular: when Blazor is genuinely the right choice
The comparison with JavaScript frameworks is usually told as a contest between languages, C# against JavaScript or TypeScript.
It is a simplification that leads to bad decisions.
The right question is not "which language do I prefer", but "which framework best solves the problems of this project, in this team, in this context".
Where Blazor has real advantages
A team with solid .NET skills and little front-end experience gains more than it might appear.
Learning React or Angular does not mean learning only the framework: you take on the entire JavaScript ecosystem, npm, bundlers, TypeScript, Jest, state management libraries.
For a .NET team building an internal interface, Blazor reaches production far sooner, because you skip the whole second apprenticeship.
Applications with complex business logic to share between front end and back end are another clear case.
With Blazor WASM you share domain classes, validators and business rules between client and server in the same project: no duplication, no implementations that drift apart over time.
A third scenario, recurring in enterprise IT everywhere: modernising WPF or Windows Forms desktop applications for the web, while keeping the existing team.
Blazor is the natural route: same logic, same language, same team.
And it is the most direct bridge to Blazor Hybrid, which reuses the same Razor components in a MAUI desktop or mobile app.
Where React and Angular win
Public applications with demanding SEO requirements, where Time to First Byte and First Contentful Paint are measured and monitored KPIs, remain the territory of React and Angular.
React with Next.js or Angular with SSR have a far more mature server-side rendering story than Blazor WASM, with broader optimisation ecosystems, tested at much larger scale.
A team with solid JavaScript or TypeScript skills has little to gain from switching stack.
The cost of learning Blazor for a JavaScript front-end developer mirrors the cost of learning React for a .NET team: real, far from trivial, and rarely sensible without a precise business reason.
The component ecosystem points the same way: npm has an order of magnitude more front-end libraries than NuGet.
Charts, maps, rich text editors and specialised components often have to be built from scratch in Blazor, or adapted from less mature libraries.
And then there is the labour market, which technical discussions tend to ignore: in most countries you will find experienced React or Angular developers far more easily than senior Blazor developers.
The reason is simple, the JavaScript ecosystem has had a larger pool of professionals for years.
If you need to hire and grow a front-end team quickly, this weighs as much as the architecture: put it on the table alongside SEO, performance and the skills you already have in house.
The practical rule
The decision criterion, stripped to the bone, fits in three lines:
| Project context | Recommended choice |
|---|---|
| Internal business application, .NET team, shared logic, no SEO requirements | Blazor |
| Public portal, critical SEO, front-end-first team, rich UI ecosystem | React or Angular |
| Public section plus restricted area | Blazor Auto for the restricted area, Static SSR or MVC for the public part |
It is the most sensible combination when you need both.
For an in-depth comparison between Blazor and React when choosing a stack, see the article Blazor vs React.
And if you are building your path as a .NET web developer and want to work out where Blazor fits in the roadmap, see how to become a web developer with .NET in 2026.
Blazor in production: the go-live checklist
Before taking a Blazor application into production, there is a set of checks that separates a quiet release from a week of emergency work.
Over the years I have followed dozens of Blazor go-lives, and I have watched the same mistakes repeat with striking regularity.
Always the same ones: the rendering mode chosen out of habit, the bundle never measured on a production build, the token validated only by the interface, the first server restart that takes everybody's session down with it.
So I condensed all of it into an operational checklist, the one I use myself before every release.
It covers the five areas where nearly all the problems of the first weeks are concentrated:
- The rendering mode: did you choose it on real requirements or on language preference?
- SEO: have you checked with URL Inspection what Google actually sees?
- Performance: have you measured TTI on a simulated 4G connection?
- Security: do the endpoints validate the token independently of the interface?
- Infrastructure: what happens to active sessions on the first restart in production?
Every question on the checklist exists because somebody, somewhere, spent a weekend answering it the hard way: in an emergency.
The checklist on its own is not enough, though, because every project has its own constraints: expected traffic, the team, the infrastructure you already run.
That is why I do not hand it out as a downloadable PDF: without knowing how to apply it to your project, you would write it off as yet another useless list found online.
The path to mastering Blazor professionally

Blazor is a mature technology, with continued investment from Microsoft at every .NET release.
In .NET 9 Auto mode is stable, AOT performance has improved, and the hybrid model with Static SSR and selective interactivity covers the great majority of real cases a team meets in production.
The technology is not the problem.
The problem is that the official documentation explains each individual concept well, but does not tell you when to use which mode, which trade-offs to accept, or which mistakes to avoid before release rather than after it.
The difference between a senior .NET developer who can pick the right Blazor mode for each context and one who chooses by hearsay shows up entirely in production.
You read it in the organic traffic, in the loading times, in the calls to technical support.
Mastering Blazor professionally means understanding the architecture, not just the syntax. The syntax can be learned in a weekend; the architecture is understood by building something real, with feedback on what you do, not by watching yet another tutorial.If you are wondering whether it is worth investing in the C# and ASP.NET Core path in order to use Blazor professionally, read also C# course or self-taught: what really pays off in 2026.
And if you want a structured path covering Blazor, ASP.NET Core and the whole .NET stack with real projects and feedback on what you build, our course is designed for exactly that.
Having read this far, you have two roads ahead of you.
The first: you close the page and go back to the project.
You will carry on choosing rendering modes by hearsay, discovering SEO problems six months after release, and paying for your training in the most expensive way there is: with emergency weekends, rewrites and calls from clients.
The second: you decide that the next architectural choice you make will be one you understand completely.
Let us be clear: the Blazor course is not for everyone.
It is not for people who collect tutorials and finish nothing.
It is not for people looking for a certificate to hang on LinkedIn.
And it is not for people who keep saying "the AI writes the code anyway": the code perhaps, but the choices that matter between WASM, Server and Auto are yours.
And in production it is your name on it, not the model's.
It is for people who want to be the one who says in the meeting "not this mode, and here is why", while everybody else nods at the wrong proposal.
If you recognise yourself in the second group, the Blazor course gives you what an article can only point at: architecture tackled on real projects, with feedback on what you build, until choosing well becomes a reflex.
You read this article for free.
Mistakes in production you pay for at full price.
Choose which you prefer.
Frequently asked questions
Yes, pure Blazor WebAssembly has structural SEO problems because pages are rendered entirely in the browser. Search engine crawlers find near-empty HTML and must wait for client-side rendering, which in Blazor WASM can take 6-12 seconds. Google claims to support SPA crawling, but the process is incomplete and unreliable compared to server-pre-rendered HTML. The solution is to use Blazor with SSR pre-rendering or Blazor Auto, which generate complete HTML on the first request and resolve the issue at the architectural level.
Blazor WebAssembly runs C# code directly in the browser via WebAssembly: no server is involved in rendering, but the browser must download the .NET runtime and application DLLs on first access (1-8 MB compressed). Blazor Server runs everything on the server and communicates with the browser via SignalR (WebSocket): the first load is immediate because the server generates ready-made HTML, but every user interaction requires a server round-trip and every user keeps an open connection. The choice depends on SEO, scale, offline requirements and user connection type.
Blazor Auto is a hybrid mode introduced in .NET 8 that combines Server and WebAssembly. On first access, components run in Server mode, so the user immediately sees rendered HTML and can interact. In parallel, the browser downloads the WebAssembly runtime in the background. Once the download is complete, or on subsequent visits thanks to cache, components automatically switch to WASM mode, eliminating the server dependency for rendering. It is the most balanced mode for applications that want an immediate first load and client-side autonomy in subsequent sessions.
It depends on the rendering mode. Pure Blazor WebAssembly is not suitable for public applications with SEO because rendering happens in the browser. Blazor Server, Blazor Auto with SSR pre-rendering, and the static server-side rendering (Static SSR) of .NET 8 generate HTML on the server and are SEO-compatible. For public portals with organic traffic, the right choice is Blazor Auto or a mixed architecture: public pages in Static SSR and interactive sections with WASM or Server depending on the use case.
Yes, on first load Blazor WebAssembly is significantly heavier than React. An optimised build with trimming and Brotli compression starts at 1.5-2 MB for a simple app and can reach 5-8 MB for complex apps. Optimised React starts at 100-300 KB. The gap is structural: Blazor WASM carries a .NET runtime into the browser. The advantage is that DLLs are cached and subsequent visits are fast. For internal applications where the first load happens once, the trade-off is acceptable; for public applications the initial weight is a real conversion problem.
In Blazor WASM, authentication typically uses JWT: the client calls a login endpoint, receives a token, and includes it in the Authorization header of every subsequent API call. The critical point is that in WASM all code is visible to the browser: real protection always sits in the server-side API endpoints, not in UI controls. The [Authorize] decorator on a WASM component hides or shows UI elements, but is not a security measure. For tokens, HttpOnly cookies are more secure than localStorage (not accessible from JavaScript in XSS scenarios). For enterprise applications, integration with Entra ID or Identity Server is the standard choice.
