Trust is earned, not given

A different perspective

2026-04-18 · Projects

DotNetCode, part 8: A React SPA and an ASP.NET Core API in one repository

ReactSpa (part of DotNetCode) answers a question every web developer eventually faces: where does the front end live? This sample puts a Vite + React + TypeScript SPA and an ASP.NET Core 10 minimal API in one repository, with both the development workflow and the production shape worked out.

Development: two servers, one proxy

dotnet run --project ReactSpa.Api     # API on :5080
cd ClientApp && npm run dev           # Vite on :5173

The Vite dev server proxies /api/* calls to the API, so the browser only ever sees one origin. You get Vite's instant hot reload for front-end work and a real .NET backend behind it — no CORS configuration to fight, because the proxy makes requests same-origin.

Production: one host

The csproj carries two MSBuild hooks: a build step that copies ClientApp/dist into the API's wwwroot, and a publish step that runs npm install + npm run build itself. The API then serves the SPA with MapFallbackToFile("index.html") — the line that makes client-side routing work, returning index.html for any path the API does not own. One web host, one deploy artifact, no separate static hosting bill.

The API itself is deliberately minimal

/api/weather and /api/echo — enough to prove the plumbing. The sample's subject is the integration, not the endpoints; the same skeleton carries any real API. For the realtime counterpart to this static-page shape, see the Blazor SignalR article; for what this looks like when it grows into a full product, see UnifiedShopping.

Repository: github.com/bobhuang1/DotNetCode/tree/master/ReactSpa