# Fetch And Send Data

Call APIs, load data into components, and handle the async lifecycle in Blazor.

- Repository: https://github.com/dotnet/skills (5787 stars)
- Category: Engineering
- License: MIT
- Last updated: 2026-11-01
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add dotnet/skills --skill fetch-and-send-data -g -a claude-code -y`
Codex: `npx skills add dotnet/skills --skill fetch-and-send-data -g -a codex -y`
Cursor: `npx skills add dotnet/skills --skill fetch-and-send-data -g -a cursor -y`
Gemini CLI: `npx skills add dotnet/skills --skill fetch-and-send-data -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add dotnet/skills`

## Description

Call APIs, load data into components, and handle the async lifecycle in Blazor. USE FOR fetching data from a backend, submitting data to an API, displaying loading/error states, registering HttpClient, building service abstractions for Auto/WebAssembly render modes. DO NOT USE for form validation (see collect-user-input), prerendering persistence (see support-prerendering), or project scaffolding (see create-blazor-project).

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Fetch and Send Data

## Step 1, Read AGENTS.md

Check **Interactivity Mode** and **Scope**:

| Mode | Data access |
|------|-------------|
| None (Static SSR) | Server-side: inject services/`DbContext`. Use `[StreamRendering]` for loading UX. |
| Server | Server-side: inject services/`DbContext`. Guard prerender with `??=` + `[PersistentState]`. |
| WebAssembly | Browser-side: `HttpClient` only. No direct server access. |
| Auto | Both server and browser. Always go through an API. |

## Step 2, Register HttpClient

Only needed when calling external APIs from Server, or always for WebAssembly/Auto. Server components accessing their own database should inject `DbContext` or a service directly.

```csharp
// Named client, requires Microsoft.Extensions.Http NuGet
builder.Services.AddHttpClient("CatalogAPI", client =>
{
    client.BaseAddress = new Uri("https://api.example.com/");
});

// Typed client
builder.Services.AddHttpClient<CatalogClient>(client =>
    client.BaseAddress = new Uri("https://api.example.com/"));
```

For WebAssembly/Auto with prerendering, register in **both** server and `.Client` `Program.cs`.

## Step 3, Fetch Data

### Simple load

```razor
@page "/products"
@inject CatalogClient Catalog

@if (products is null)
{
    <p>Loading…</p>
}
else
{
    @foreach (var p in products)
    {
        <p>@p.Name, @p.Price.ToString("C")</p>
    }
}

@code {
    private Product[]? products;

    protected override async Task OnInitializedAsync()
    {
        products = await Catalog.GetProductsAsync();
    }
}
```

No error handling needed in the simplest case, wrap the component usage in `<ErrorBoundary>` at the parent/layout level to catch unhandled exceptions.

### Static SSR, StreamRendering

Without `[StreamRendering]`, the user sees nothing until `OnInitializedAsync` completes:

```razor
@attribute [StreamRendering]
```

Only affects Static SSR. No effect on interactive components.

### Prerendering guard

The rest: https://github.com/dotnet/skills/blob/HEAD/plugins/dotnet-blazor/skills/fetch-and-send-data/SKILL.md
