DemoPreview

DemoPreview renders a demo component from your docs project and shows that component's .razor file in the Code tab. Use it for examples a razor:preview fence can't express : anything that needs a @code block, state, a loop, or injected services.

Basic use

markdown
<DemoPreview Component="PackageFamilyDemo" Title="Package family" Layout="stretch" />
Package family
ShellDocs.Components
Layouts, chrome and the content primitives.
ShellDocs.Markdown
The Markdig pipeline and component slots.
ShellDocs.Core
Navigation graph and search index.
ShellDocs.Tokens
Design tokens as CSS variables.
<CardGrid Columns="@Columns">
    @foreach (var package in Packages.Take(Count))
    {
        <Card Title="@package.Name" Description="@package.Summary" />
    }
</CardGrid>

@code {
    /// <summary>Number of grid columns on desktop.</summary>
    [Parameter] public int Columns { get; set; } = 2;

    /// <summary>How many packages to list, in dependency order.</summary>
    [Parameter] public int Count { get; set; } = 4;

    private record Package(string Name, string Summary);

    private static readonly Package[] Packages =
    [
        new("ShellDocs.Components", "Layouts, chrome and the content primitives."),
        new("ShellDocs.Markdown", "The Markdig pipeline and component slots."),
        new("ShellDocs.Core", "Navigation graph and search index."),
        new("ShellDocs.Tokens", "Design tokens as CSS variables."),
        new("ShellDocs.CLI", "init, add, dev and build."),
    ];
}

The Code tab shows PackageFamilyDemo.razor as it is on disk, @code block included. The reader copies a complete, working component.

Setting it up

  1. Put demos in a folder

    Any folder in the docs project works. This site uses Components/Demos.

    • Components
      • Demos
        • PackageFamilyDemo.razor
  2. Register the demos and point at their source
    csharp
    builder.Services.AddShellDocs(o =>
    {
        o.RegisterComponentsFromAssembly<App>("MyDocs.Components.Demos");
        o.DemoSourceRoot = Path.Combine(builder.Environment.ContentRootPath, "Components", "Demos");
    });
    

    DemoSourceRoot is searched recursively for a file named after the component.

  3. Ship the source files

    The Razor SDK leaves .razor files out of publish output. Copy them with a None item so the source is there after dotnet publish and shelldocs build:

    xml
    <ItemGroup>
      <None Include="Components/Demos/**/*.razor"
            CopyToOutputDirectory="PreserveNewest"
            CopyToPublishDirectory="PreserveNewest" />
    </ItemGroup>
    

Interactive demos and static hosts

A demo with @onclick handlers needs a running Blazor app. On a static export the demo renders in its initial state and doesn't respond. Demos that only compute what to render, like the one above, work everywhere. See Deployment.

Code for something other than the demo

By default the Code tab shows the demo's .razor file. Put <CodeTab> children inside the tag and it shows those instead, one tab each : the same example in another syntax, or for another platform. SyncKey switches them together across the site and Caption adds a note to the toolbar. See Code tabs on previews.

The same demo twice

The frame's anchor is demo-{component}. When a page shows one demo more than once, give each its own Id:

markdown
<DemoPreview Component="PackageFamilyDemo" Id="family-compact" />

Errors

A red panel replaces the example when the component isn't registered, when DemoSourceRoot isn't set, or when no matching .razor file is found under it. The message never includes the server path.

Props

Prop Type Default Description
ComponentRequired string — Name of the registered demo component, and of its .razor file.
Title string? — Title in the frame header.
Layout string? center center, stretch or scroll.
Id string? demo-{component} Anchor id for the frame.
SyncKey string? — Sync key for its code tabs.
Caption string? PreviewCaption Muted note in the toolbar.
CodeTabs IReadOnlyList<PreviewCodeTab>? — Code tabs, when the preview is written in a .razor file. In markdown, use CodeTab children.

See also