Quick start

Add Inertia.Net to an ASP.NET Core app, create the root template and render your first page.

On this page

Already using the starter template? Its services, middleware, root template and frontend are configured for you. These steps are for adding Inertia to an existing app or building one manually.

Every app needs the same four things:

  1. Register Inertia and the protocol middleware

  2. Add a root template with the Inertia tokens

  3. Render a page from an endpoint

  4. Connect a client and run Vite

1. Register the services

Choose one backend style. All three use the same protocol middleware and the same Render(...) result.

Text
// Program.cs
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddValidation();                    // .NET 10 source-generated validation
builder.Services.AddAntiforgery(o => o.HeaderName = InertiaHeaders.XsrfToken);
builder.Services.AddInertia(o =>
{
    o.Share("appName", "Demo");
    o.Pages.Directory = "ClientApp/pages";
});

var app = builder.Build();

app.UseStaticFiles();                                // serves wwwroot/build (Vite output)
app.UseInertia();                                    // before the endpoints
app.UseInertiaAntiforgery();                         // XSRF-TOKEN cookie; 419 for unsafe requests without it

app.MapGet("/", () => Render("Home", new InertiaProps
{
    ["greeting"] = "Hello from .NET",
}));

app.Run();

Why AddValidation and antiforgery up front?

AddValidation() enables the Minimal API integration used by .WithInertiaValidation(). UseInertiaAntiforgery() issues the XSRF-TOKEN cookie and validates every unsafe request, so forms work from the first commit.

See Precognition for live form validation.

2. Add the root template

The root template is an HTML file in the content root. The default name is app.html.

Text
<!-- app.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>My app</title>
  @inertiaHead
  @viteReactRefresh
  @vite("ClientApp/app.tsx")
</head>
<body>
  @inertia
</body>
</html>

Remove @viteReactRefresh for Vue and Svelte. @inertia is required. The other tokens are described in Pages and responses.

Make sure app.html is copied to the output and publish directory:

Text
<ItemGroup>
  <Content Include="app.html" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
</ItemGroup>

3. Create the page component

The page name passed to Render must match the client resolver. With @inertiajs/vite the resolver maps ClientApp/pages/** automatically.

Text
// ClientApp/pages/Home.tsx
export default function Home({ greeting }: { greeting: string }) {
  return <h1>{greeting}</h1>
}

The client entry only needs to start Inertia:

Text
// ClientApp/app.tsx
import { createInertiaApp } from '@inertiajs/react'

createInertiaApp()

Not using @inertiajs/vite?

Pass your own resolve and setup functions to createInertiaApp. The client setup page shows both forms for React, Vue and Svelte.

4. Run it

Install dependencies and start Vite from the project directory with your package manager:

Package managerInstall dependenciesStart ViteBuild assets
npmnpm installnpm run devnpm run build
Bunbun installbun run devbun run build
pnpmpnpm installpnpm run devpnpm run build
Yarnyarn installyarn run devyarn run build

Keep Vite running in terminal 1. Start ASP.NET Core in terminal 2:

Text
dotnet watch     # Development environment

Open the URL printed by dotnet watch (not the Vite URL). The first visit to / should display “Hello from .NET”.

For production, run the build command from your row, then publish the app:

Text
dotnet publish -c Release

Deploy wwwroot/build and app.html with the published app.

Where to go next