A full-stack web application template featuring a .NET 8 backend with React/Vite frontend, using OIDC authentication with Microsoft Entra ID.
- Backend: .NET 8 Web API with ASP.NET Core
- Frontend: React 19 with Vite, TypeScript, and TanStack Router/Query/Table
- Authentication: OIDC with Microsoft Entra ID (Azure AD)
- Styling: Tailwind CSS
- Development: Hot reload for both frontend and backend
-
Clone the repository
git clone https://github.com/ucdavis/web-app-template/ cd web-app-template
-
Open In DevContainer
- Open the project folder in Visual Studio Code.
- Click the prompt to open in container (or manually select from the command palette).
Using the DevContainer is optional, but it will get you the right version of dotnet + node, plus install all dependencies and setup a local SQL instance for you
-
Start the application
npm start
This command automatically installs dependencies (if needed) and starts both the .NET backend and Vite frontend with hot reload enabled.
Optional: If dependencies change, you can manually reinstall with
npm install && cd client && npm install && cd ..
but you shouldn't have to, thenpm start
should handle it. -
Access the application
The application will auto launch in your browser (to http://localhost:5173).
If you want to access endpoints individually, you can do so at the following URLs:
- Frontend: http://localhost:5173
- Backend API: http://localhost:5165 (nothing to see, but /api/* has the direct API endpoints)
- API Documentation (Swagger): http://localhost:5165/swagger/index.html
- Health check: http://localhost:5165/health
The backend requires a SQL Server connection string. By default appsettings.Development.json
has a connection string configured for the local SQL Server instance.
When you want to specify your own DB connection, provide it by setting the DB_CONNECTION
environment variable (for example in a .env
file) or by updating ConnectionStrings:DefaultConnection
in appsettings.*.json
(.env
is recommended)
We use OIDC with Microsoft Entra ID (Azure AD) for authentication. The auth flow doesn't use any secrets and the settings in appsettings.*.json
are sufficient for local development.
When you are ready to get your own, go to Microsoft Entra ID and create a new application registration. Set the redirect url to http://localhost:5165/signin-oidc
and check the box for "ID tokens".
You might also want to set the publisher domain to ucdavis.edu and fill in the other general branding info.
The health check endpoint (/health
) is configured to return the status of the application and its dependencies. It includes a database health check to ensure the SQL Server connection is healthy. See Health Checks.
The backend is configured with hot reload via dotnet watch
. Any changes to C# files will automatically restart the server.
The frontend uses Vite's hot module replacement (HMR). Changes to React components, TypeScript files, and CSS will be reflected immediately.
- Frontend routes requiring authentication redirect to the backend's login endpoint
- Backend handles OIDC flow with Microsoft Entra ID
- Upon successful authentication, a same-site cookie is set
- Frontend API calls automatically include the authentication cookie
- Backend validates the cookie for protected endpoints
- Run
cd client && npm test
to execute the Vitest suite once. - Use
npm run test:watch
insideclient/
for red/green feedback while you work. - Tests run against a jsdom environment with Testing Library so you do not need the backend running.
- Run
dotnet test
from the repository root to execute the .NET test project included inapp.sln
. - Alternatively, target the project directly with
dotnet test tests/server.tests/server.tests.csproj
. - The tests use EF Core's in-memory provider (see
tests/server.tests/TestDbContextFactory.cs
) so no SQL Server instance is required.
├── client/ # React frontend
│ ├── src/
│ │ ├── routes/ # TanStack Router routes
│ │ ├── queries/ # TanStack Query hooks
│ │ ├── lib/ # API client and utilities
│ │ └── shared/ # Shared components
│ ├── package.json
│ └── vite.config.ts
├── server/ # .NET backend
│ ├── Controllers/ # API controllers
│ ├── Helpers/ # Utility classes
│ ├── Properties/ # Launch settings
│ ├── Program.cs # Application entry point
│ └── server.csproj
├── package.json # Root package.json with start script
└── app.sln # Visual Studio solution file
npm start
- Starts both backend and frontend with hot reload
npm run dev
- Start Vite development servernpm run build
- Build for productionnpm run lint
- Run ESLintnpm run preview
- Preview production buildnpm test
- Run tests
dotnet run
- Start the .NET applicationdotnet watch
- Start with hot reloaddotnet build
- Build the applicationdotnet test
- Run tests