Generated banner for Fluentui Blazor
Generated logo for Fluentui Blazor

Fluentui Blazor

GitHubOfficialFirst committed by AClerboisDistributed by GitHub

  • Skill
  • Tool integration
  • Software development
  • MIT
  • No issues found

From the author

Guide for using the Microsoft Fluent UI Blazor component library (Microsoft.FluentUI.AspNetCore.Components NuGet package) in Blazor applications. Use this when the user is building a Blazor app with Fluent UI components, setting up the library, using FluentUI components like FluentButton, FluentDataGrid, FluentDialog, FluentToast, FluentNavMenu, FluentTextField, FluentSelect, FluentAutocomplete, FluentDesignTheme, or any component prefixed with "Fluent". Also use when troubleshooting missing providers, JS interop issues, or theming.
— the description by AClerbois

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides essential guidance for developers using the Microsoft.FluentUI.AspNetCore.Components NuGet package. It covers library setup, service registration, and the correct usage of Fluent UI components such as FluentDataGrid, FluentNavMenu, and various form controls. The guide emphasizes the library's specific patterns, including the use of provider components for services, strongly-typed icon handling, and the service-based dialog pattern, while highlighting common pitfalls like manual script inclusion and incorrect form binding.

What it does

  • Explains how to register Fluent UI services in Program.cs.
  • Details the implementation of required provider components for dialogs, toasts, and messages.
  • Provides patterns for using Fluent UI components like FluentDataGrid, FluentNavMenu, and FluentSelect.
  • Outlines the correct approach for handling icons via the dedicated NuGet package.
  • Demonstrates the service-based dialog pattern for modal interactions.
  • Offers best practices for theming and design tokens using FluentDesignTheme.

When to use it

  • When setting up a new Blazor project with Fluent UI components.
  • When implementing complex UI elements like data grids, navigation menus, or modal dialogs.
  • When troubleshooting issues related to component rendering, theming, or service registration.
  • When integrating Fluent UI form components into Blazor EditForms.

Advantages

  • Ensures correct library configuration and service lifetime management.
  • Promotes consistent UI patterns across the application.
  • Prevents common errors like manual script injection or incorrect component binding.
  • Provides clear, idiomatic examples for advanced components like FluentDataGrid and FluentAutocomplete.

Usage examples

“How do I add a toast notification in my Blazor component?”
Inject IToastService and call ToastService.ShowSuccess or similar methods, ensuring FluentToastProvider is present in the root layout.
“How do I use FluentDataGrid with an IQueryable data source?”
Bind the Items parameter to your IQueryable collection and define columns using PropertyColumn or TemplateColumn components.
“Why are my Fluent UI dialogs not showing up?”
Verify that FluentDialogProvider is added to your root layout and that you are using the IDialogService to trigger the dialog.
“How do I display a Fluent icon in my app?”
Install the Microsoft.FluentUI.AspNetCore.Components.Icons package and use the FluentIcon component with a strongly-typed icon class.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/github/fluentui-blazor/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip fluentui-blazor.zip -d .agents/skills

Documentation by AClerbois

Fluent UI Blazor — Consumer Usage Guide

This skill teaches how to correctly use the Microsoft.FluentUI.AspNetCore.Components (version 4) NuGet package in Blazor applications.

Critical Rules

The library auto-loads all CSS and JS via Blazor's static web assets and JS initializers. Never tell users to add <script> or <link> tags for the core library.

2. Providers are mandatory for service-based components

These provider components MUST be added to the root layout (e.g. MainLayout.razor) for their corresponding services to work. Without them, service calls fail silently (no error, no UI).

<FluentToastProvider />
<FluentDialogProvider />
<FluentMessageBarProvider />
<FluentTooltipProvider />
<FluentKeyCodeProvider />
3. Service registration in Program.cs
builder.Services.AddFluentUIComponents();

// Or with configuration:
builder.Services.AddFluentUIComponents(options =>
{
    options.UseTooltipServiceProvider = true;  // default: true
    options.ServiceLifetime = ServiceLifetime.Scoped; // default
});

ServiceLifetime rules:

  • ServiceLifetime.Scoped — for Blazor Server / Interactive (default)

  • ServiceLifetime.Singleton — for Blazor WebAssembly standalone

  • ServiceLifetime.Transient — throws NotSupportedException

4. Icons require a separate NuGet package
dotnet add package Microsoft.FluentUI.AspNetCore.Components.Icons

Usage with a @using alias:

@using Icons = Microsoft.FluentUI.AspNetCore.Components.Icons

<FluentIcon Value="@(Icons.Regular.Size24.Save)" />
<FluentIcon Value="@(Icons.Filled.Size20.Delete)" Color="@Color.Error" />

Pattern: Icons.[Variant].[Size].[Name]

  • Variants: Regular, Filled

  • Sizes: Size12, Size16, Size20, Size24, Size28, Size32, Size48

Custom image: Icon.FromImageUrl("/path/to/image.png")

Never use string-based icon names — icons are strongly-typed classes.

5. List component binding model

FluentSelect<TOption>, FluentCombobox<TOption>, FluentListbox<TOption>, and FluentAutocomplete<TOption> do NOT work like <InputSelect>. They use:

  • Items — the data source (IEnumerable<TOption>)

  • OptionText — Func<TOption, string?> to extract display text

  • OptionValue — Func<TOption, string?> to extract the value string

  • SelectedOption / SelectedOptionChanged — for single selection binding

  • SelectedOptions / SelectedOptionsChanged — for multi-selection binding

<FluentSelect Items="@countries"
              OptionText="@(c => c.Name)"
              OptionValue="@(c => c.Code)"
              @bind-SelectedOption="@selectedCountry"
              Label="Country" />

NOT like this (wrong pattern):

@* WRONG — do not use InputSelect pattern *@
<FluentSelect @bind-Value="@selectedValue">
    <option value="1">One</option>
</FluentSelect>
6. FluentAutocomplete specifics
  • Use ValueText (NOT Value — it's obsolete) for the search input text

  • OnOptionsSearch is the required callback to filter options

  • Default is Multiple="true"

<FluentAutocomplete TOption="Person"
                    OnOptionsSearch="@OnSearch"
                    OptionText="@(p => p.FullName)"
                    @bind-SelectedOptions="@selectedPeople"
                    Label="Search people" />

@code {
    private void OnSearch(OptionsSearchEventArgs<Person> args)
    {
        args.Items = allPeople.Where(p =>
            p.FullName.Contains(args.Text, StringComparison.OrdinalIgnoreCase));
    }
}
7. Dialog service pattern

Do NOT toggle visibility of <FluentDialog> tags. The service pattern is:

  1. Create a content component implementing IDialogContentComponent<TData>:

public partial class EditPersonDialog : IDialogContentComponent<Person>
{
    [Parameter] public Person Content { get; set; } = default!;

    [CascadingParameter] public FluentDialog Dialog { get; set; } = default!;

    private async Task SaveAsync()
    {
        await Dialog.CloseAsync(Content);
    }

    private async Task CancelAsync()
    {
        await Dialog.CancelAsync();
    }
}
  1. Show the dialog via IDialogService:

[Inject] private IDialogService DialogService { get; set; } = default!;

private async Task ShowEditDialog()
{
    var dialog = await DialogService.ShowDialogAsync<EditPersonDialog, Person>(
        person,
        new DialogParameters
        {
            Title = "Edit Person",
            PrimaryAction = "Save",
            SecondaryAction = "Cancel",
            Width = "500px",
            PreventDismissOnOverlayClick = true,
        });

    var result = await dialog.Result;
    if (!result.Cancelled)
    {
        var updatedPerson = result.Data as Person;
    }
}

For convenience dialogs:

await DialogService.ShowConfirmationAsync("Are you sure?", "Yes", "No");
await DialogService.ShowSuccessAsync("Done!");
await DialogService.ShowErrorAsync("Something went wrong.");
8. Toast notifications
[Inject] private IToastService ToastService { get; set; } = default!;

ToastService.ShowSuccess("Item saved successfully");
ToastService.ShowError("Failed to save");
ToastService.ShowWarning("Check your input");
ToastService.ShowInfo("New update available");

FluentToastProvider parameters: Position (default TopRight), Timeout (default 7000ms), MaxToastCount (default 4).

9. Design tokens and themes work only after render

Design tokens rely on JS interop. Never set them in OnInitialized — use OnAfterRenderAsync.

<FluentDesignTheme Mode="DesignThemeModes.System"
                   OfficeColor="OfficeColor.Teams"
                   StorageName="mytheme" />
10. FluentEditForm vs EditForm

FluentEditForm is only needed inside FluentWizard steps (per-step validation). For regular forms, use standard EditForm with Fluent form components:

<EditForm Model="@model" OnValidSubmit="HandleSubmit">
    <DataAnnotationsValidator />
    <FluentTextField @bind-Value="@model.Name" Label="Name" Required />
    <FluentSelect Items="@options"
                  OptionText="@(o => o.Label)"
                  @bind-SelectedOption="@model.Category"
                  Label="Category" />
    <FluentValidationSummary />
    <FluentButton Type="ButtonType.Submit" Appearance="Appearance.Accent">Save</FluentButton>
</EditForm>

Use FluentValidationMessage and FluentValidationSummary instead of standard Blazor validation components for Fluent styling.

Reference files

For detailed guidance on specific topics, see:

Files

references/SETUP.md

Setup and Configuration

NuGet Packages

PackagePurpose
Microsoft.FluentUI.AspNetCore.ComponentsCore component library (required)
Microsoft.FluentUI.AspNetCore.Components.IconsIcon package (optional, recommended)
Microsoft.FluentUI.AspNetCore.Components.EmojisEmoji package (optional)
Microsoft.FluentUI.AspNetCore.Components.DataGrid.EntityFrameworkAdapterEF Core adapter for DataGrid (optional)
Microsoft.FluentUI.AspNetCore.Components.DataGrid.ODataAdapterOData adapter for DataGrid (optional)

Program.cs Registration

builder.Services.AddFluentUIComponents();
Configuration Options (LibraryConfiguration)
PropertyTypeDefaultNotes
UseTooltipServiceProviderbooltrueRegisters ITooltipService. If true, you MUST add <FluentTooltipProvider> to layout
RequiredLabelMarkupStringRed *Custom markup for required field indicators
HideTooltipOnCursorLeaveboolfalseClose tooltip when cursor leaves both anchor and tooltip
ServiceLifetimeServiceLifetimeScopedOnly Scoped or Singleton. Transient throws!
ValidateClassNamesbooltrueValidates CSS class names against ^-?[_a-zA-Z]+[_a-zA-Z0-9-]*$
CollocatedJavaScriptQueryStringFunc<string, string>?v={version}Cache-busting for JS files
ServiceLifetime by hosting model
Hosting modelServiceLifetime
Blazor ServerScoped (default)
Blazor WebAssembly StandaloneSingleton
Blazor Web App (Interactive)Scoped (default)
Blazor Hybrid (MAUI)Singleton

MainLayout.razor Template

@inherits LayoutComponentBase

<FluentLayout>
    <FluentHeader Height="50">
        My App
    </FluentHeader>

    <FluentStack Orientation="Orientation.Horizontal" HorizontalGap="0" Style="height: 100%;">
        <FluentNavMenu Width="250" Collapsible="true" Title="Navigation">
            <FluentNavLink Href="/" Icon="@(Icons.Regular.Size20.Home)" Match="NavLinkMatch.All">Home</FluentNavLink>
            <FluentNavLink Href="/counter" Icon="@(Icons.Regular.Size20.NumberSymbol)">Counter</FluentNavLink>
            <FluentNavGroup Title="Settings" Icon="@(Icons.Regular.Size20.Settings)">
                <FluentNavLink Href="/settings/general">General</FluentNavLink>
                <FluentNavLink Href="/settings/profile">Profile</FluentNavLink>
            </FluentNavGroup>
        </FluentNavMenu>

        <FluentBodyContent>
            <FluentStack Orientation="Orientation.Vertical" Style="padding: 1rem;">
                @Body
            </FluentStack>
        </FluentBodyContent>
    </FluentStack>
</FluentLayout>

@* Required providers — place after FluentLayout *@
<FluentToastProvider />
<FluentDialogProvider />
<FluentMessageBarProvider />
<FluentTooltipProvider />
<FluentKeyCodeProvider />

@* Theme — place at root *@
<FluentDesignTheme Mode="DesignThemeModes.System"
                   OfficeColor="OfficeColor.Teams"
                   StorageName="mytheme" />

Or use the convenience component:

<FluentMainLayout Header="@header"
                  NavMenuContent="@navMenu"
                  Body="@body"
                  HeaderHeight="50"
                  NavMenuWidth="250"
                  NavMenuTitle="Navigation" />

@code {
    private RenderFragment header = @<span>My App</span>;
    private RenderFragment navMenu = @<div>
        <FluentNavLink Href="/">Home</FluentNavLink>
    </div>;
    private RenderFragment body = @<div>@Body</div>;
}

_Imports.razor

Add this to your _Imports.razor:

@using Microsoft.FluentUI.AspNetCore.Components
@using Icons = Microsoft.FluentUI.AspNetCore.Components.Icons

Static Web Assets

No manual <link> or <script> tags are needed. The library uses:

  • CSS: reboot.css (normalization) + component-scoped CSS — auto-loaded via static web assets

  • JS: lib.module.js — auto-loaded via Blazor's JS initializer system

  • Component-specific JS (e.g. DataGrid, Autocomplete) — lazy-loaded on demand

All served from _content/Microsoft.FluentUI.AspNetCore.Components/.

Services Registered

Services automatically registered by AddFluentUIComponents():

ServiceImplementationPurpose
GlobalStateGlobalStateShared application state
IToastServiceToastServiceToast notifications (needs FluentToastProvider)
IDialogServiceDialogServiceDialogs and panels (needs FluentDialogProvider)
IMessageServiceMessageServiceMessage bars (needs FluentMessageBarProvider)
IKeyCodeServiceKeyCodeServiceKeyboard shortcuts (needs FluentKeyCodeProvider)
IMenuServiceMenuServiceContext menus
ITooltipServiceTooltipServiceTooltips (needs FluentTooltipProvider, opt-in via UseTooltipServiceProvider)

Requirements and compatibility

Written for: GitHub Copilot

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

First committed by
GitHub avatar of AClerboisAClerbois
Publisher
GitHub (Official)
Distributed by
GitHub
Source
github/awesome-copilot · skills/fluentui-blazor · commit 797337f
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced
Contributors
AClerbois

AutoGineer is not affiliated with or endorsed by AClerbois or GitHub.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download fluentui-blazor.zip