Creating a modern multi-page web application that combines the power of ASP.NET for backend logic and Vite.js for frontend development offers a fast, modular, and scalable solution. This guide walks you through the setup, starting with the essential dependencies.
Step 1: Dependencies
To get started, make sure you have the following installed:
Required Tools
- .NET SDK (7.0 or later)
- Node.js (v18 or later)
- Vite.js (installed via npm)
- A code editor like Visual Studio Code
- Project Structure
Your project will be structured like this:
/MyApp /ClientApp ← Vite.js frontend /Controllers ← ASP.NET MVC controllers /Models ← ASP.NET Model /Properties ← ASP.NET launch setting /Views ← Razor views (optional) /wwwroot ← Final build path Program.cs Startup.cs or minimal hosting
1: Set Up ASP.NET Core Backend
Create a new ASP.NET Core Web App (MVC or Empty):
dotnet new web -n MyApp
cd MyApp
code .
2. Configure Program.cs to serve static files and fallback to index.html in production:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseStaticFiles();
app.MapFallbackToFile("index.html");
}
app.UseRouting();
app.MapControllers();
app.Run();
3. Setup Routing Controller for Client App
Modify Controllers/HomeController.cs as follows:
using Microsoft.AspNetCore.Mvc;
public class HomeController : Controller
{
[HttpGet("{*url}", Order = int.MaxValue)]
public IActionResult Index(string url)
{
return View();
}
}
You can remove the default Privacy() action and its view since this will be handled by your SPA.
Step 2: Add WeatherForecast API
- Create WeatherForecastController.cs Controller
Should create controller inside
/Controller/Api/WeatherForecastController.cs
using Microsoft.AspNetCore.Mvc;
namespace MyApp.Controllers.Api; // change the namespace
[ApiController]
[Route("api/[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild",
"Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
});
}
}
- Create a Model for the Controller
Should create model inside /Models/WeatherForecast.cs
namespace MyApp.Models // change the namespace
public class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
- Update Razor Views
Clear all inside the /Views/Home/Index.cshtml and add:
@{
Layout = "_Layout";
}
Modify the _Layout file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - MyApp</title>
<!-- Only for the React Refresh, for other templates remove this -->
<script type="module">
import { injectIntoGlobalHook } from "http://localhost:5173/@react-refresh";
injectIntoGlobalHook(window);
window.$RefreshReg$ = () => {};
window.$RefreshSig$ = () => (type) => type;
</script>
<!-- End Refresh -->
<script type="module" src="http://localhost:5173/@vite/client"></script>
</head>
<body>
@RenderBody()
<script type="module" src="http://localhost:5173/src/main.tsx"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>
Here I use React template in Vite so we need to add the React refresh lines. For other templates we can remove them.
Step 3: Set Up React Frontend with Vite
- Create your Vite app:
npm create vite@latest ClientApp
Package name: clientapp
Template: react, react-ts, or vue (your choice)
- Navigate and install dependencies:
cd ClientApp
npm i
npm i react-router axios
- Recommended Folder Structure
/src
/components ← Header, Footer
/pages ← Home, WeatherList
main.tsx
App.tsx
- Setup Axios API: /src/api/weather.tsx
import axios from "axios"; //can use JavaScript Fetch
export const getWeatherForecast = () =>
axios.get("/api/weatherforecast").then((res) => res.data);
// fetch()
- Create Home Page and Weather Page
import { useEffect, useState } from "react";
import { getWeatherForecast } from "../api/weather";
function WeatherList() {
const [forecasts, setForecasts] = useState([]);
useEffect(() => {
getWeatherForecast().then(setForecasts);
}, []);
return (
<div>
<h2>Weather Forecast</h2>
<ul>
{forecasts.map((f, i) => (
<li key={i}>
{f.date}: {f.summary} ({f.temperatureC}°C)
</li>
))}
</ul>
</div>
);
}
export default WeatherList;
function Home() {
return (
<div className="container mt-5">
<div className="row justify-content-center">
<div className="col-md-8 text-center">
<h1 className="mb-4">Welcome to the Movie Application!</h1>
<p className="lead">Discover, explore, and enjoy our collection of movies.</p>
<p>Use the navigation bar to browse through different sections.</p>
</div>
</div>
</div>
);
}
export default Home;
- Configure Routing in /src/App.tsx
import { BrowserRouter, Routes, Route } from "react-router";
import { WeatherList } from "./pages/WeatherList";
import Home from "./pages/Home";
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/weather" element={<WeatherList />} />
</Routes>
</BrowserRouter>
);
}
export default App;
Final Step: Run the App
Open two terminals:
Terminal 1: ASP.NET Core Backend
dotnet dev-certs https --trust
dotnet watch run
# for https
dotnet watch -lp https
Terminal 2: React Frontend with Vite
cd ClientApp
npm run dev
In single Powershell based run both at a time
Start-Process -WorkingDirectory ".\ClientApp" -NoNewWindow -FilePath "powershell" -ArgumentList "npm run dev"
dotnet watch run
Summary
You now have a scalable, modern full-stack application using:
ASP.NET Core for APIs and static file hosting
React (or other template) + Vite for fast frontend development
Axios + React Router for API calls and navigation
This setup is easily extendable to include authentication, advanced state management, and deployment pipelines.
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.