{
  "schema": "https://ai-atoms.com/schemas/skill-v1.json",
  "type": "skill",
  "id": "skill/create-blazor-project",
  "version": "1.0.1",
  "name": "create-blazor-project",
  "description": "Create a new ASP.NET Core web application or web site using Blazor. USE FOR: creating a new Blazor web app, scaffolding a new web project, starting a new web site, choosing render modes (Static SSR, Interactive Server, Interactive WebAssembly, Auto), running dotnet new blazor with the right options, setting up initial project structure. DO NOT USE FOR: adding features to existing projects, changing how an existing app renders, or component authoring (use author-component).",
  "system_prompt_fragment": "# Create a Blazor Web App\n\n## Before You Start — Gather Requirements\n\nIf the user's request doesn't make the following clear, ask before scaffolding:\n\n1. **What does the app do?** List the main screens/features (e.g., \"product catalog with search and shopping cart\").\n2. **What kind of interactivity is needed?** Displaying data and forms? Real-time updates? Offline support? Rich drag-and-drop UI?\n3. **Deployment environment?** Internet-facing? Intranet? Mobile users on slow connections?\n4. **Authentication needed?** Anonymous? Individual accounts? Organizational (Azure AD)?\n\n## Pick the Right Interactivity Level\n\nBlazor render modes are a progression scale. Start at the simplest level that satisfies the requirements and only move up when there's a concrete reason.\n\n```\nStatic SSR ──→ SSR + Enhanced Nav ──→ Interactive Server ──→ Interactive WebAssembly\n simplest                                                           most complex\n```\n\n### Decision Rules\n\n| If the app needs... | Use | Why |\n|---|---|---|\n| Display data, simple forms, links between pages | **Static SSR** (`-int None`) | No JS runtime, no circuit, no WebAssembly download. Forms work via HTML POST. Enhanced navigation makes it feel snappy. |\n| Everything above + a few components with client-side behavior (live search, real-time updates, complex form wizards) | **Interactive Server, per-page** (`-int Server`) | Only the components that need interactivity opt in with `@rendermode`. The rest stays static. Server-side execution, full .NET access, no API layer needed. |\n| Most pages need rich interactivity (dashboards, drag-and-drop, chat) | **Interactive Server, global** (`-int Server -ai`) | Every component is interactive by default. Consistent UX, simpler mental model. Trade-off: every user holds a SignalR circuit on the server. |\n| Network latency is a problem, users are on mobile/poor connections, or the app must work offline | **Interactive WebAssembly** (`-int WebAssembly`) | Code runs in the browser. Eliminates round-trip latency but requires a `.Client` project, API layer for data access, and downloads the .NET runtime to the browser on first visit. For offline support, enable PWA: add a service worker and manifest after scaffolding (not included in the template by default). |\n| Fast initial load (Server) + low latency after (WebAssembly) | **Interactive Auto** (`-int Auto`) | First visit uses Server; subsequent visits use cached WebAssembly runtime. Most complex setup — see Auto constraints below. Only choose when both Server and WebAssembly constraints apply. |\n\n**Default recommendation:** Start with `-int Server` (per-page). It covers the vast majority of apps. Upgrade to global or WebAssembly only when a specific requirement demands it.\n\n### Auto Mode Constraints\n\nAuto mode means your component code runs on the server first, then in the browser on subsequent visits. This creates real constraints:\n\n- **All interactive components must live in the `.Client` project** — same as WebAssembly.\n- **No direct server access** from interactive components — no EF `DbContext`, no file system, no server-only services. All data access must go through HTTP APIs.\n- **Both `Program.cs` files must register matching services** — the server and client DI containers must both provide implementations for any service an interactive component injects.\n- **Code must not assume its execution environment** — no `HttpContext` access, no browser-only APIs without `RendererInfo` guards.\n- **Test in both modes** — a component that works on Server during development may break on WebAssembly in production (second visit). Test both paths.\n\n### Don'ts\n\n- Don't pick WebAssembly \"because it's cool\" — it adds a `.Client` project, forces API-mediated data access, and downloads ~10MB to the browser on first visit.\n- Don't pick Auto unless you can articulate why Server alone and WebAssembly alone are both insufficient.\n- Don't pick global interactivity for apps where most pages are read-only content — per-page keeps the static pages fast and reduces server memory.\n\n## Scaffold the Project\n\n### Static SSR Only (display data + simple forms)\n\n```shell\ndotnet new blazor -o {AppName} -int None\n```\n\nNo interactive runtime. Enhanced navigation enabled by default via `blazor.web.js`.\n\n### Interactive Server, Per-Page (recommended default)\n\n```shell\ndotnet new blazor -o {AppName} -int Server\n```\n\nPages are static by default. Add `@rendermode InteractiveServer` to components that need interactivity.\n\n### Interactive Server, Global\n\n```shell\ndotnet new blazor -o {AppName} -int Server -ai\n```\n\nAll pages interactive via `<Routes @rendermode=\"InteractiveServer\" />` in `App.razor`.\n\n### Interactive WebAssembly, Per-Page\n\n```shell\ndotnet new blazor -o {AppName} -int WebAssembly\n```\n\nCreates `{AppName}` (server) and `{AppName}.Client` (WebAssembly) projects. Interactive components must live in `.Client`.\n\n### Interactive WebAssembly, Global\n\n```shell\ndotnet new blazor -o {AppName} -int WebAssembly -ai\n```\n\n### Interactive Auto, Per-Page\n\n```shell\ndotnet new blazor -o {AppName} -int Auto\n```\n\n### Interactive Auto, Global\n\n```shell\ndotnet new blazor -o {AppName} -int Auto -ai\n```\n\n### With Authentication\n\nAppend `-au Individual` to any command above:\n\n```shell\ndotnet new blazor -o {AppName} -int Server -au Individual\n```\n\n`-au Individual` scaffolds ASP.NET Core Identity with SQLite (CLI) or SQL Server (Visual Studio). Identity pages are always static SSR — they do not use interactive render modes.\n\nThe `blazor` template only supports `-au Individual`. For organizational auth (Microsoft Entra ID, Azure AD B2C), scaffold with `-au Individual` first, then replace the Identity provider with `Microsoft.Identity.Web` / OIDC middleware and configure the tenant in `appsettings.json`.\n\n## What the Template Creates\n\n### Single project (Static SSR, Server)\n\n```\n{AppName}/\n├── Components/\n│   ├── App.razor              # Root component — sets <HeadOutlet> and <Routes>\n│   ├── Routes.razor           # Wraps <Router> with route discovery\n│   ├── Layout/\n│   │   ├── MainLayout.razor   # App shell with nav, header, footer\n│   │   └── MainLayout.razor.css\n│   └── Pages/\n│       └── Home.razor         # @page \"/\" — first page\n├── Program.cs                 # Service registration and middleware\n├── wwwroot/                   # Static files (CSS, images)\n└── {AppName}.csproj\n```\n\n### Two projects (WebAssembly, Auto)\n\n```\n{AppName}/                     # Server project — hosts the app\n├── Components/                # Server-only components (static SSR pages, layouts)\n│   ├── App.razor\n│   ├── Routes.razor\n│   └── Layout/\n├── Program.cs                 # Server Program.cs\n└── {AppName}.Client/          # Client project — WebAssembly components\n    ├── Pages/                 # Interactive components go HERE\n    ├── Program.cs             # Client Program.cs\n    └── _Imports.razor\n```\n\n**Rule:** Components using `InteractiveWebAssembly` or `InteractiveAuto` must live in the `.Client` project. They can reference shared code but cannot reference server-only types (EF `DbContext`, server-side services).\n\n## Program.cs Wiring\n\nThe template generates the correct `Program.cs` for the chosen mode. Verify these registrations match your intent:\n\n### Static SSR Only\n\n```csharp\n// Program.cs\nbuilder.Services.AddRazorComponents();\n\n// ...\n\napp.MapRazorComponents<App>();\n```\n\n### Server (per-page or global)\n\n```csharp\nbuilder.Services.AddRazorComponents()\n    .AddInteractiveServerComponents();\n\n// ...\n\napp.MapRazorComponents<App>()\n    .AddInteractiveServerRenderMode();\n```\n\n### WebAssembly (per-page or global)\n\n```csharp\n// Server Program.cs\nbuilder.Services.AddRazorComponents()\n    .AddInteractiveWebAssemblyComponents();\n\n// ...\n\napp.MapRazorComponents<App>()\n    .AddInteractiveWebAssemblyRenderMode()\n    .AddAdditionalAssemblies(typeof({AppName}.Client._Imports).Assembly);\n```\n\n```csharp\n// Client Program.cs\nbuilder.Services.AddAuthorizationCore();\n// Register HttpClient, other client-side services\n```\n\n## Create Project AGENTS.md\n\nAfter scaffolding, create an `AGENTS.md` file in the project root (next to the `.csproj`). For two-project setups, put it in the server project root.\n\nPick the matching template from `assets/agents-md/` based on the chosen mode:\n\n| Mode | Template file |\n|------|--------------|\n| Static SSR (`-int None`) | `assets/agents-md/ssr-none.md` |\n| Server, per-page (`-int Server`) | `assets/agents-md/server-per-page.md` |\n| Server, global (`-int Server -ai`) | `assets/agents-md/server-global.md` |\n| WebAssembly, per-page (`-int WebAssembly`) | `assets/agents-md/webassembly-per-page.md` |\n| WebAssembly, global (`-int WebAssembly -ai`) | `assets/agents-md/webassembly-global.md` |\n| Auto, per-page (`-int Auto`) | `assets/agents-md/auto-per-page.md` |\n| Auto, global (`-int Auto -ai`) | `assets/agents-md/auto-global.md` |\n\nCopy the template contents into the project's `AGENTS.md` and replace every `{AppName}` with the actual project name. If auth was scaffolded (`-au Individual`), add an `## Authentication` section noting that ASP.NET Core Identity is configured and that Identity pages under `Components/Account/` are always static SSR — do not add `@rendermode` to them.\n\n**After scaffolding the project and creating AGENTS.md, continue implementing the features the user requested.** Remove default template pages (Counter, Weather) and replace them with the actual application pages.\n\n### Auto (per-page or global)\n\n```csharp\n// Server Program.cs\nbuilder.Services.AddRazorComponents()\n    .AddInteractiveServerComponents()\n    .AddInteractiveWebAssemblyComponents();\n\n// ...\n\napp.MapRazorComponents<App>()\n    .AddInteractiveServerRenderMode()\n    .AddInteractiveWebAssemblyRenderMode()\n    .AddAdditionalAssemblies(typeof({AppName}.Client._Imports).Assembly);\n```\n\n## App.razor — Global vs Per-Page\n\nThe difference between global and per-page interactivity is entirely in `App.razor`:\n\n### Per-page (default)\n\n```razor\n<!DOCTYPE html>\n<html>\n<head>\n    <HeadOutlet />\n</head>\n<body>\n    <Routes />\n    <script src=\"_framework/blazor.web.js\"></script>\n</body>\n</html>\n```\n\nNo `@rendermode` on `<Routes>` or `<HeadOutlet>`. Individual pages opt in.\n\n### Global\n\n```razor\n<!DOCTYPE html>\n<html>\n<head>\n    <HeadOutlet @rendermode=\"InteractiveServer\" />\n</head>\n<body>\n    <Routes @rendermode=\"InteractiveServer\" />\n    <script src=\"_framework/blazor.web.js\"></script>\n</body>\n</html>\n```\n\nReplace `InteractiveServer` with `InteractiveWebAssembly` or `InteractiveAuto` as appropriate.\n\n## After Scaffolding\n\n1. **Verify it builds:** `dotnet build`\n2. **Run it:** `dotnet run` (in the server project if two-project setup)\n3. **Add your first page:** Create a `.razor` file in `Components/Pages/` (server project) or `Pages/` (`.Client` project for WebAssembly components)\n\n## Don'ts\n\n- Don't use `dotnet new blazorwasm` — that creates a standalone WebAssembly SPA without server-side rendering. Use the `blazor` template with `-int WebAssembly` instead.\n- Don't manually add `AddInteractiveServerComponents()` to a project created with `-int None` and expect it to work — you also need the `@rendermode` directives and potentially `App.razor` changes. Re-scaffold if the mode needs to change fundamentally.\n- Don't put WebAssembly-targeted components in the server project — they'll work during prerender but fail after handoff.",
  "applicable_domains": [
    "code",
    "dotnet",
    "engineering"
  ],
  "invocation": [
    "/create-blazor-project"
  ],
  "tags": [
    "dotnet-blazor",
    "dotnet",
    "csharp",
    "microsoft"
  ],
  "authored_by": "anthropics",
  "source_url": "https://github.com/dotnet/skills/blob/main/plugins/dotnet-blazor/skills/create-blazor-project/SKILL.md",
  "lifecycle": "stable",
  "category": "dotnet",
  "provenance": {
    "source": "dotnet/skills",
    "source_url": "https://github.com/dotnet/skills/blob/main/plugins/dotnet-blazor/skills/create-blazor-project/SKILL.md",
    "author": "Microsoft / .NET Foundation",
    "license": "MIT",
    "notes": "Imported by scripts/import-anthropic-skills.py."
  }
}