Building a data table in Blazor is usually straightforward. QuickGrid takes care of much of the work for you, including displaying columns, sorting data, and handling pagination.
The situation becomes a little more interesting when the application uses Static Server-Side Rendering (Static SSR).
With an interactive Blazor application, a component can react to events such as button clicks and update its state without a full navigation. Static SSR works differently. The server renders the component, and the browser receives the resulting HTML.
So how can a sortable QuickGrid still work without relying on interactive component events?
The answer is URL-based sorting and pagination.
Instead of keeping the sorting state only inside the component, QuickGrid can represent that state in the query string. A sortable column can navigate to a URL such as:
/products?sort=Price&order=desc
The server receives the request, QuickGrid reads the sorting information, and the page is rendered again using the requested order.
This approach fits naturally with Static SSR because the browser is simply following a URL.
Understanding Static SSR
Static SSR means that the server generates the HTML for a Blazor component and sends it to the browser.
The browser does not need an interactive Blazor connection just to display the rendered page.
A simplified request looks like this:
Browser
|
| HTTP Request
v
Blazor Server
|
| Render Component
v
HTML Response
|
v
Browser
If the user clicks a normal link, another HTTP request can be made:
Browser
|
| /products?sort=Price&order=desc
v
Blazor Server
|
| Render sorted data
v
Browser
This is different from an interactive event:
Browser
|
| @onclick
v
Interactive Blazor connection
|
v
Component state changes
For applications that don't need continuous interaction, Static SSR can provide a simpler rendering model.
Why QuickGrid and Static SSR Work Well Together
A table normally needs two common interactions:
Sorting
Pagination
Both can be expressed through URLs.
For example:
/products?sort=Name&order=asc
and:
/products?page=3&sort=Name&order=asc
The URL contains enough information for the server to recreate the same table view.
This is a useful architectural pattern because the state is not hidden inside the browser.
The URL itself describes the current view.
Creating a QuickGrid
Let's create a simple product model.
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Category { get; set; } = string.Empty;
public decimal Price { get; set; }
public bool IsAvailable { get; set; }
}
For demonstration purposes, we can create some sample data:
private readonly List<Product> Products =
[
new()
{
Id = 1,
Name = "Laptop",
Category = "Electronics",
Price = 75000,
IsAvailable = true
},
new()
{
Id = 2,
Name = "Mechanical Keyboard",
Category = "Accessories",
Price = 5500,
IsAvailable = true
},
new()
{
Id = 3,
Name = "Monitor",
Category = "Electronics",
Price = 22000,
IsAvailable = true
},
new()
{
Id = 4,
Name = "Mouse",
Category = "Accessories",
Price = 1800,
IsAvailable = true
}
];
Now add QuickGrid to the Razor component.
@using Microsoft.AspNetCore.Components.QuickGrid
<QuickGrid Items="Products.AsQueryable()">
<PropertyColumn Property="p => p.Id"
Title="ID" />
<PropertyColumn Property="p => p.Name"
Title="Name"
Sortable="true" />
<PropertyColumn Property="p => p.Category"
Title="Category"
Sortable="true" />
<PropertyColumn Property="p => p.Price"
Title="Price"
Sortable="true" />
<PropertyColumn Property="p => p.IsAvailable"
Title="Available" />
</QuickGrid>
The Sortable="true" property tells QuickGrid that users should be able to sort the column.
How URL-Based Sorting Works
In .NET 11, QuickGrid uses URL-based navigation for sorting and pagination by default. The sorting information can be represented using query-string parameters. (learn.microsoft.com)
Suppose the user clicks the Price column.
The URL can become:
/products?sort=Price&order=asc
Clicking the column again can change the direction:
/products?sort=Price&order=desc
The page is then rendered using that sorting state.
The flow is:
Click Price
|
v
URL changes
|
v
Server receives request
|
v
QuickGrid reads sorting state
|
v
Data is sorted
|
v
New HTML is rendered
This is why the feature works with Static SSR.
Why This Is Better Than a Custom Sorting Handler
A common approach in older applications is to write a custom click handler.
For example:
<button @onclick="SortByPrice">
Price
</button>
Then:
private void SortByPrice()
{
Products = Products
.OrderBy(p => p.Price)
.ToList();
}
This works well in an interactive component.
But it is tied to interactive event handling.
For a Static SSR page, URL navigation is a better fit because the sorting operation can be represented as a normal navigation.
You also get another useful benefit: the current sorting state can be bookmarked or shared.
Column Titles and Sorting
There is an important detail when using URL-based sorting.
QuickGrid uses the column title when representing sorting state in the URL. (learn.microsoft.com)
For example:
<PropertyColumn Property="p => p.Price"
Title="Price"
Sortable="true" />
can result in:
?sort=Price&order=asc
Now consider changing the title:
<PropertyColumn Property="p => p.Price"
Title="Product Price"
Sortable="true" />
The sorting identifier changes as well.
This is worth remembering if users may bookmark or share URLs.
A column title can look like simple display text, but when it participates in URL state, changing it can affect navigation behavior.
Adding Pagination
Pagination can be added using PaginationState.
@code {
private PaginationState pagination = new()
{
ItemsPerPage = 10
};
}
Then pass the state to QuickGrid:
<QuickGrid Items="Products.AsQueryable()"
Pagination="pagination">
<PropertyColumn Property="p => p.Id"
Title="ID" />
<PropertyColumn Property="p => p.Name"
Title="Name"
Sortable="true" />
<PropertyColumn Property="p => p.Category"
Title="Category"
Sortable="true" />
<PropertyColumn Property="p => p.Price"
Title="Price"
Sortable="true" />
</QuickGrid>
<Paginator State="pagination" />
The page number can then be represented in the URL.
For example:
/products?page=2
When sorting is also active:
/products?page=2&sort=Price&order=desc
This gives the application a complete description of the current table state.
Why URL State Helps Users
Imagine a support engineer investigating a customer issue.
They open the product table and sort it by price. They then move to page 4.
Without URL state, they might send a screenshot to another developer.
With URL state, they can share the page URL.
For example:
/products?page=4&sort=Price&order=desc
The other developer can open the same view.
This can also be useful for:
Bookmarks
Browser refresh
Browser Back and Forward
Support tickets
Internal documentation
Reproducing a data view
Static SSR Does Not Mean "No Interactivity"
It is important not to misunderstand Static SSR.
Static SSR does not mean that the entire application can never have interactive behavior.
A Blazor application can use different rendering approaches depending on the page or component.
For example:
Join the conversation! Your thoughts help the community grow.