Previously, in Part 1, we created
ClinicApp with the Blazor Web App template, ran it, and clicked a counter
button powered entirely by C#.
Today we slow down and look around. When you open the ClinicApp folder, you're
greeted by a dozen files you didn't write. It's tempting to shrug and say "template stuff"
— but that's how projects start feeling like magic, and magic is exactly what we're here to
remove. By the end of this tour, every file will have a job you can name. Here's the map:
Think of the app as a theater production. Someone turns on the lights, someone builds the stage, someone decides which scene plays. Let's meet the crew.
Program.cs — the ignition
Every .NET app starts here. Program.cs builds the app, registers the
services it will need (we'll add our own PatientService here
later in the series), wires up Blazor, and finally starts the web server. It runs once, at
startup — like turning the key in a car. You'll edit it occasionally; you'll rarely need to
stare at it.
Components/App.razor — the HTML shell
View the source of any page in your running app and you'll see a normal HTML document:
<html>, <head>, <body>, stylesheet
links. That skeleton lives in App.razor. It's the outermost wrapper around
everything else — the theater building itself.
Components/Routes.razor — the router
When you visit /counter, how does Blazor know which page to show? That's the
router's job. Routes.razor looks at the URL, finds the
component whose address matches, and renders it. No match? It shows a "not found" message
instead. It's the box office, checking your ticket and pointing you to the right seat.
_Imports.razor — shared usings
In C#, you write using statements at the top of each file. Components need
those too — but repeating them in every single .razor file would get old fast.
_Imports.razor collects the common ones once, and every component in the
project gets them automatically. Quietly convenient, and it will do us a favor in Part 3.
Components/Layout/MainLayout.razor — the frame
Notice how every page in ClinicApp shares the same sidebar and top row? Pages
don't repeat that markup — it lives in the layout. MainLayout.razor
is the picture frame; each page is the picture slotted inside it. Change the frame once,
and every page changes with it. Next to it you'll also find
ReconnectModal.razor, a recent addition to the template: the built-in
reconnection UI that appears automatically if the app's live connection to the server drops.
Components/Pages/ — the pages themselves
Here's a secret that simplifies everything: Home.razor and
Counter.razor are not special "page files." They are ordinary components that
happen to have an address, declared with a @page directive at the top. Give
any component an address and it becomes a page — that's the whole trick. Our own
Patients.razor and PatientDetails.razor pages will join this
folder later in the series.
wwwroot/ — static files
Anything the browser should fetch as-is — stylesheets, images, favicons — lives in
wwwroot. If it's a plain file with no C# in it, this is its home.
ClinicApp.csproj — the project file
One sentence, as promised: this small file tells the .NET SDK what kind of project this is and which packages it depends on.
Reading Counter.razor like a local
Let's put the tour to work and read a real file. Open
Components/Pages/Counter.razor:
@page "/counter"
@rendermode InteractiveServer
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
Every component you'll ever write has up to three zones, and here they all are:
- Directives at the top — lines starting with
@.@page "/counter"gives the component its address, and@rendermode InteractiveServeris what makes the page respond to clicks. For now, just know that interactive pages need that line under@page— the full story of render modes is Part 12's job. - Markup in the middle — HTML, with C# values dropped in wherever you see
an
@, like@currentCount. - Code at the bottom — a
@codeblock holding plain C#: fields, methods, whatever the component needs.@onclick="IncrementCount"is the bridge between zones: a click in the markup runs a method in the code.
Note: Did you notice how often the word component came up? The shell is a component. The router is a component. The layout, the pages — components all the way down. "Everything is a component" is the single most useful idea in Blazor, and it's the theme of this entire series.
What's next
You now know the whole cast — nothing in ClinicApp should feel like magic
anymore. So let's start writing components of our own. In
Part 3, we'll build
PatientCard.razor, our first reusable piece of UI, and use it to put our first
patients on screen. See you there!