Web Project Overview
In the BlazorForKids architecture, the solution template is split into two main projects: the Domain project and the Web project. The Domain project contains the backend logic, while the Web project is the UI layer. This separation of concerns helps you build a scalable, maintainable application.
Project Structure
The Web project template in BlazorForKids is a modified version of the standard Blazor project template. One of the key differences is the presence of a root folder named Source, which organizes your UI components and pages into three main sub-folders:
- Main: This folder contains essential files required for a Blazor application to run,
such as
App.razor
,MainLayout.razor
,Routes.razor
, andError.razor
. These files are generally not edited unless you have a very specific reason to change them, which is why they are isolated in the Main folder. - Components: Here you will find reusable components that are available across your entire project.
For example, the
ApplicationLogo
component is placed here to display the name and logo of your application in the header. As your project evolves, you can add more shared components in this folder. - Features: This folder is intended to hold your application's features. In this context, "features" refer to the core parts of your application such as layouts, pages, and specialized components. Technically, all of your project-specific content goes into the Features folder. While this structure is only a suggestion, it provides a good starting point for organizing your project.
Application Entry Point
Every web application needs an entry point. In a Blazor application, the entry point is defined by App.razor
,
which is located in the Main folder. However, App.razor
functions like a layout—it contains the shared
background configuration of your app but does not hold the actual content.
The actual content is provided by Blazor components that have a @page
attribute with a specific URL.
For example, the home page of your application is typically represented by a component such as Home.razor
with the URL "/"
.
This Home.razor
page serves as the entry point for user interaction.
Defining Features
At the Features level, you define the core functionality of your application. This includes:
- Layouts and Pages: These are the building blocks for the user interface, defining how content is organized and displayed.
- Specialized Components: Components specific to a feature or a business process that are used only within a particular section of the application.
Although the suggested structure (with separate folders for Main, Components, and Features) is provided to help you maintain a clean and organized codebase, you are free to organize your project in a way that best fits your needs.
Summary
In summary, the BlazorForKids Web project is designed to be a robust and flexible UI layer that works in tandem with the Domain project. The predefined structure helps you manage common application components:
- The Main folder contains critical application files that rarely change.
- The Components folder houses shared components like the application logo.
- The Features folder is intended for your business-specific pages and components.
By following these guidelines, even beginners can quickly understand the architecture of a BlazorForKids project and build upon it to create a customized and maintainable application.
Understanding the Concept of a Feature
In the BlazorForKids Web project, the term Feature refers to a self-contained section of your application that focuses on a specific functionality or business process. Features are more than just folders — they help you organize, structure, and scale your application in a clean and maintainable way.
Let’s imagine you’re building an application to help employees manage their tasks and KPIs (Key Performance Indicators). Instead of placing all components and pages into a single folder or page, it's better to divide the application into clearly defined sections — or features.
Example: Breaking an App into Features
Here’s how you might logically structure the application into multiple features:
- Home: A landing page with a dashboard-style overview. It might show summaries, shortcuts, or quick access to other features.
- Settings: A feature where you manage application-level configuration — such as adding employees, defining KPIs, and assigning roles.
- My KPIs: A section where employees interact with their own KPIs — they can update values, add comments, or track their own performance.
- Tasks: A dedicated space for creating, assigning, updating, and commenting on tasks, possibly linked to specific KPIs or goals.
- Reports: A place to visualize performance through graphs, tables, or even exportable presentations used during review meetings.
Why Feature-Based Structure Matters
Dividing your app into features provides both technical and user experience advantages:
- Improved Developer Workflow: You can work on one feature at a time. It’s easier to track progress, collaborate with teammates, and say, "This feature is done."
- Clean UI Organization: Each screen focuses on a single goal, which avoids overwhelming the user with too much information at once.
- Navigation Made Simple: Your app layout can include a header or side menu that links to each feature, making it easier for users to switch between them.
- Code Reusability: Each feature can have its own layout, components, services, and even its own style if needed — without interfering with other parts of the app.
A Must-Have, Not Just a Nice-to-Have
While organizing your app by features may sound like a nice design pattern, in practice, it's essential for building modern web applications. As your project grows, this structure will help you scale, maintain, and evolve your app without chaos.
In the BlazorForKids Web template, you’ll find a Features
folder already included and ready for you to use.
This is where your layouts, pages, and domain-specific components should live — one folder per feature, one step closer to clean architecture.
BlazorForKids UI Structure: Layouts, Pages, and Components
Now that we've explained what a Feature is in the BlazorForKids architecture, it's time to look at the core building blocks of the UI: Layouts, Pages, and Components. Each feature typically includes one or more of these elements.
In BlazorForKids, every UI feature is structured using a layout class that defines:
- How the layout looks and behaves
- What pages belong to it
- Which reusable components are defined for that layout
The Role of the Layout Class
Each layout is implemented as a partial class that must inherit from IBkApplicationLayout
.
This interface requires you to implement three methods:
LayoutDesigner()
– Used to define layout structure, headers, menus, and navigation itemsPagesDesigner()
– Used to declare and configure the pages that are part of the layoutComponentsDesigner()
– Used to register data-driven components (like grid views) for use within pages
publicpartialclassHomeLayout:IBkApplicationLayout
{
publicvoidLayoutDesigner(IBkLayoutBuilderbuilder)
{
builder.CreateHeader(header=>
{
header.DisplayComponent<ApplicationLogo>();
header.CreateMenu(=>
{
.AddMenuItem<HomePage>();
.AddMenuItem<AboutPage>();
.AddMenuItem<ContactPage>();
.AddMenuItem<LoginPage>(=>
{
.HiddenToAuthenticatedUsers();
});
.AddMenuItem<LogoutPage>(=>
{
.VisibleToAuthenticatedUsers();
});
});
});
}
publicvoidPagesDesigner(IBkPageBuilderbuilder)
{
builder.CreatePage("HomePage",page=>
{
page.PageLink.Text("Home");
page.PageLink.Url("/");
page.PageTitleBar.AddMenuItems(=>
{
.AddMenuItem<DepartmentsPage>();
});
page.Content(content=>
{
content.DisplayComponent<EmployeeGridView>();
});
});
builder.CreatePage("AboutPage",page=>
{
page.PageLink.Text("About");
page.Content(content=>
{
content.Rows(1);
content.Columns(3);
content.DisplayComponent<BkPlaceHolder>();
content.DisplayComponent<BkPlaceHolder>();
content.DisplayComponent<BkPlaceHolder>();
});
});
builder.CreatePage("ContactPage",page=>
{
page.PageLink.Text("Contact");
page.Content(content=>
{
content.Rows(3);
content.Columns(3);
content.DisplayComponent<BkPlaceHolder>();
content.DisplayComponent<BkPlaceHolder>();
content.DisplayComponent<BkPlaceHolder>();
content.DisplayComponent<BkPlaceHolder>(2,3);
});
});
builder.CreatePage("DepartmentsPage",page=>
{
page.PageLink.Text("Departments");
page.Content(content=>
{
content.DisplayComponent<DepartmentGridView>();
});
});
}
publicvoidComponentsDesigner(IBkComponentsBuilderbuilder)
{
builder.CreateGridView<EmployeeModel,Employee>("EmployeeGridView");
builder.CreateGridView<DepartmentModel,Department>("DepartmentGridView");
}
}
Important Conventions and Rules
When creating layouts and pages, there are some conventions and requirements you must follow to ensure proper generation and integration:
- Layout Attribute: Every layout class must be decorated with a
[Layout]
attribute to specify its parent layout. This makes it possible to nest layouts and create structured navigation hierarchies. - Class Naming: The layout class must be named using the suffix
Layout
(e.g.,HomeLayout
), or the source generator will ignore it. - Partial Keyword: The layout class must be declared as
partial
. This is mandatory for the source generator to inject logic correctly. - Page Naming: All page classes must use the
Page
suffix (e.g.,HomePage
,AboutPage
), or the framework will not recognize them as pages. - Page Routing: Only the root page (usually
HomePage
) requires a manually defined route (such as"/"
). All other pages will automatically receive routes based on the layout and page names. You can override these routes if needed. - Layout-Pages Binding: All pages defined inside a layout will always be rendered within that layout. If you want a page to appear under a different layout, you must define the page in that new layout and set its parent layout accordingly.
Working with Components
Reusable, data-driven components (such as grid views, forms, etc.) must be defined inside the ComponentsDesigner()
method.
Here, you register and configure the components so they can be used inside any page or layout.
Once a component is defined, it is not restricted to a specific layout or page. You can use it across your application wherever it makes sense.
Summary
The layout class serves as the heart of each feature’s UI definition. It binds together the layout, pages, and components, giving you a clear and centralized place to configure your application’s structure.
This design helps developers keep their code clean and modular while giving users a structured and intuitive experience.
For more details on how to configure layouts, pages, and components, please continue reading the sections below: