### Setup and Configuration Source: https://context7.com/mergehez/inertianetcore/llms.txt Guides on setting up Inertia.js with ASP.NET Core, including service registration, middleware configuration, and Vite integration. ```APIDOC ## AddInertia - Register Inertia Services Registers Inertia services in the dependency injection container with configurable options for JSON serialization, session handling, SSR, and history encryption. ```csharp using InertiaNetCore.Extensions; using InertiaNetCore.Models; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); // Basic setup builder.Services.AddInertia(); // Or with custom options builder.Services.AddInertia(options => { // Custom root view (default: ~/Views/App.cshtml) options.RootView = "~/Views/App.cshtml"; // Enable Server-Side Rendering options.SsrEnabled = true; options.SsrUrl = "http://127.0.0.1:13714/render"; // Enable global history encryption options.EncryptHistory = true; // Configure session options options.ConfigureSession = sessionOptions => { sessionOptions.Cookie.Name = "InertiaSession"; sessionOptions.IdleTimeout = TimeSpan.FromMinutes(30); }; // Custom JSON serialization (using Newtonsoft.Json) var jsonSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), ReferenceLoopHandling = ReferenceLoopHandling.Ignore, }; options.Json = InertiaJsonOptions.Create(jsonSettings); }); ``` ## UseInertia - Enable Inertia Middleware Enables Inertia middleware in the request pipeline, handling version checking and automatic asset refresh. ```csharp var app = WebApplication.Build(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllers(); // Enable Inertia middleware app.UseInertia(); app.Run(); ``` ## AddViteHelper - Configure Vite Integration Registers the Vite helper for frontend asset management with support for development hot reloading and production builds. ```csharp // Basic Vite setup builder.Services.AddViteHelper(); // Or with custom options builder.Services.AddViteHelper(options => { options.PublicDirectory = "wwwroot"; // Public directory path options.BuildDirectory = "build"; // Build output directory options.HotFile = "hot"; // Hot reload indicator file options.ManifestFilename = "manifest.json"; // Vite manifest filename }); ``` ``` -------------------------------- ### Install InertiaNetCore Package Source: https://github.com/mergehez/inertianetcore/blob/main/README.md Commands to install the library via Package Manager or .NET CLI. ```shell Install-Package InertiaNetCore ``` ```shell dotnet add package InertiaNetCore ``` -------------------------------- ### Enable Inertia in Program.cs Source: https://github.com/mergehez/inertianetcore/blob/main/README.md Register Inertia and Vite services and middleware in the application startup file. ```csharp using InertiaNetCore.Extensions; [...] builder.Services.AddInertia(); builder.Services.AddViteHelper(); // assuming you are using Vite [...] app.UseInertia(); ``` -------------------------------- ### Enable Server-Side Rendering Source: https://github.com/mergehez/inertianetcore/blob/main/README.md Configure SSR by updating the layout file and enabling the option in Program.cs. ```diff @using InertiaNetCore @model InertiaNetCore.InertiaPage My App + @await Inertia.Head(Model) @await Inertia.Html(Model) @Vite.Input("src/app.ts") ``` ```csharp builder.Services.AddInertia(options => { options.SsrEnabled = true; // You can optionally set a different URL than the default. options.SsrUrl = "http://127.0.0.1:13714/render"; // default }); ``` -------------------------------- ### Create Root View Source: https://github.com/mergehez/inertianetcore/blob/main/README.md Define the base HTML structure for the Inertia application using the InertiaPage model. ```html @using InertiaNetCore @model InertiaPage My App @await Inertia.Html(Model) @Vite.Input("src/app.ts") ``` -------------------------------- ### Configure Server-Side Rendering in Program.cs Source: https://context7.com/mergehez/inertianetcore/llms.txt Enable SSR in your application by setting `SsrEnabled` to true and providing the `SsrUrl` in the Inertia configuration within `Program.cs`. ```csharp // Enable SSR in Program.cs builder.Services.AddInertia(options => { options.SsrEnabled = true; options.SsrUrl = "http://127.0.0.1:13714/render"; // SSR server URL }); ``` -------------------------------- ### Core API: Inertia.Render Source: https://context7.com/mergehez/inertianetcore/llms.txt Demonstrates how to use the `Inertia.Render` method to render page components with props in ASP.NET Core controllers. ```APIDOC ## Inertia.Render - Render Page Components Renders an Inertia page component with the specified props. Returns an `IActionResult` that handles both initial page loads and subsequent Inertia requests. ### Request Example ```csharp using InertiaNetCore; using InertiaNetCore.Models; using Microsoft.AspNetCore.Mvc; [Route("/")] public class HomeController : Controller { [HttpGet] public IActionResult Index() { return Inertia.Render("pages/PageIndex", new InertiaProps { ["Title"] = "Welcome to My App", ["Users"] = new[] { "Alice", "Bob", "Charlie" }, ["Stats"] = new { Visits = 1234, Signups = 56 } }); } [Route("about")] public IActionResult About() { return Inertia.Render("pages/PageAbout", new InertiaProps { ["Name"] = "InertiaNetCore", ["Version"] = "0.0.15" }); } // Using Dictionary instead of InertiaProps [Route("profile")] public IActionResult Profile() { return Inertia.Render("pages/Profile", new Dictionary { ["User"] = new { Name = "John", Email = "john@example.com" } }); } } ``` ``` -------------------------------- ### Configure Vite Helper Source: https://github.com/mergehez/inertianetcore/blob/main/README.md Register the Vite helper service to automatically load assets and enable HMR. ```csharp using InertiaNetCore.Extensions; [...] builder.Services.AddViteHelper(); // Or with options (default values shown) builder.Services.AddViteHelper(options => { options.PublicDirectory = "wwwroot"; options.BuildDirectory = "build"; options.HotFile = "hot"; options.ManifestFilename = "manifest.json"; }); ``` -------------------------------- ### Redirect Back with Inertia.Back Source: https://context7.com/mergehez/inertianetcore/llms.txt Returns to the previous page using the Referer header, supporting optional flash messages. ```csharp [HttpPost] public async Task Update([FromBody] UpdateUserRequest request) { if (!ModelState.IsValid) { // Validation errors are automatically passed return Inertia.Back(); } await _userService.UpdateAsync(request); // Back with single flash message return Inertia.Back().WithFlash("success", "Profile updated!"); // Or with multiple flash messages return Inertia.Back().WithFlash(new Dictionary { ["success"] = "Profile updated!", ["info"] = "Email verification sent." }); } ``` -------------------------------- ### Configure Vite Integration with AddViteHelper Source: https://context7.com/mergehez/inertianetcore/llms.txt Registers the Vite helper for frontend asset management. Supports development hot reloading and production builds. ```csharp // Basic Vite setup builder.Services.AddViteHelper(); // Or with custom options builder.Services.AddViteHelper(options => { options.PublicDirectory = "wwwroot"; // Public directory path options.BuildDirectory = "build"; // Build output directory options.HotFile = "hot"; // Hot reload indicator file options.ManifestFilename = "manifest.json"; // Vite manifest filename }); ``` -------------------------------- ### Configure JSON Serialization Source: https://github.com/mergehez/inertianetcore/blob/main/README.md Customize JSON serialization settings for Inertia, such as switching to Newtonsoft.Json. ```csharp builder.Services.AddInertia(options => { var options = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), ReferenceLoopHandling = ReferenceLoopHandling.Ignore, }; o.Json = InertiaJsonOptions.Create(options); // there is also an optional parameter to customize the "Serialize" method }); ``` -------------------------------- ### Register Inertia Services with AddInertia Source: https://context7.com/mergehez/inertianetcore/llms.txt Registers Inertia services in the dependency injection container. Configure options for JSON serialization, session handling, SSR, and history encryption. ```csharp using InertiaNetCore.Extensions; using InertiaNetCore.Models; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); // Basic setup builder.Services.AddInertia(); // Or with custom options builder.Services.AddInertia(options => { // Custom root view (default: ~/Views/App.cshtml) options.RootView = "~/Views/App.cshtml"; // Enable Server-Side Rendering options.SsrEnabled = true; options.SsrUrl = "http://127.0.0.1:13714/render"; // Enable global history encryption options.EncryptHistory = true; // Configure session options options.ConfigureSession = sessionOptions => { sessionOptions.Cookie.Name = "InertiaSession"; sessionOptions.IdleTimeout = TimeSpan.FromMinutes(30); }; // Custom JSON serialization (using Newtonsoft.Json) var jsonSettings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver(), ReferenceLoopHandling = ReferenceLoopHandling.Ignore, }; options.Json = InertiaJsonOptions.Create(jsonSettings); }); ``` -------------------------------- ### Inertia.NET Core HTML Integration Source: https://github.com/mergehez/inertianetcore/blob/main/README.md Include this HTML structure in your main layout file to integrate Inertia.NET Core with Vite. Ensure Vite's input is correctly referenced. ```html My App @await Inertia.Html(Model) @Vite.Input("src/app.ts") ``` -------------------------------- ### Defer Prop Loading with Inertia.Defer Source: https://context7.com/mergehez/inertianetcore/llms.txt Loads props after the initial page render to improve perceived performance, with support for batch grouping. ```csharp [HttpGet] public IActionResult Profile() { return Inertia.Render("pages/Profile", new InertiaProps { // Immediate props - loaded with initial render ["User"] = _userService.GetCurrentUser(), // Deferred prop - loads after initial render ["Posts"] = Inertia.Defer(async () => { await Task.Delay(1000); // Simulate slow query return await _postService.GetUserPostsAsync(); }), // Grouped deferred props - load together ["Followers"] = Inertia.Defer(() => _socialService.GetFollowers(), "social"), ["Following"] = Inertia.Defer(() => _socialService.GetFollowing(), "social"), ["Likes"] = Inertia.Defer(() => _socialService.GetLikes(), "social"), // Another group ["Comments"] = Inertia.Defer(() => _commentService.GetRecent(), "activity"), ["Notifications"] = Inertia.Defer(() => _notificationService.GetAll(), "activity") }); } ``` -------------------------------- ### Set Flash Messages Source: https://github.com/mergehez/inertianetcore/blob/main/README.md Use Inertia.Flash or WithFlash to send temporary session messages to the frontend. ```csharp [HttpDelete("{id:int}")] public async Task Destroy(int id) { // find user // delete user Inertia.Flash("success", "User deleted."); // set it anywhere in the app return Redirect("/users"); // or one-liner in case you use Inertia.Back() return Inertia.Back().WithFlash("success", "User deleted."); } ``` -------------------------------- ### Share Global Data with Inertia.Share Source: https://context7.com/mergehez/inertianetcore/llms.txt Use to make data available to all Inertia responses via middleware or extension methods. ```csharp // In Program.cs - using extension method app.AddInertiaSharedData(httpContext => new InertiaProps { ["Auth"] = new InertiaProps { ["Token"] = httpContext.User.FindFirst("token")?.Value, ["Username"] = httpContext.User.Identity?.Name, ["IsAuthenticated"] = httpContext.User.Identity?.IsAuthenticated ?? false }, ["AppName"] = "My Application" }); // Or using middleware directly app.Use(async (context, next) => { Inertia.Share(new InertiaProps { ["Auth"] = new InertiaProps { ["Token"] = "abc123", ["Username"] = "CurrentUser" } }); // Share individual key-value pair Inertia.Share("AppVersion", "1.0.0"); await next(); }); ``` -------------------------------- ### Share Data with Views Source: https://github.com/mergehez/inertianetcore/blob/main/README.md Use middleware or the AddInertiaSharedData extension to inject global props into Inertia views. ```csharp using InertiaNetCore; using InertiaNetCore.Extensions; using InertiaNetCore.Models; [...] app.Use(async (context, next) => { Inertia.Share( new InertiaProps { ["Auth"] = new InertiaProps { ["Token"] = "123456789", ["Username"] = "Mergehez", } }); await next(); }); // you can also use AddInertiaSharedData extension method to do the same thing app.AddInertiaSharedData(httpContext => new InertiaProps { ["Auth"] = new InertiaProps { ["Token"] = "123456789", ["Username"] = "Mergehez", } }); ``` -------------------------------- ### Configure History Encryption Source: https://github.com/mergehez/inertianetcore/blob/main/README.md Enable or manage history encryption globally or per-request. ```csharp builder.Services.AddInertia(options => { options.EncryptHistory = true; }); ``` ```csharp Inertia.EncryptHistory(); ``` ```csharp Inertia.ClearHistory(); ``` -------------------------------- ### Vite Configuration for Inertia.NET Core Source: https://github.com/mergehez/inertianetcore/blob/main/README.md Configure vite.config.js to use laravel-vite-plugin for asset management and Vue support. Set up build output directory and enable hot module replacement. ```javascript import vue from '@vitejs/plugin-vue'; import { defineConfig } from 'vite'; import path from 'path'; import laravel from 'laravel-vite-plugin'; import { mkdirSync } from 'node:fs'; const outDir = '../../wwwroot/build'; mkdirSync(outDir, { recursive: true }); export default defineConfig({ plugins: [ laravel({ input: ['src/app.ts', 'src/app.scss'], publicDirectory: outDir, refresh: true, }), vue({ template: { transformAssetUrls: { base: null, includeAbsolute: false, }, }, }), ], resolve: { alias: { '@': path.resolve(__dirname, 'src'), }, }, build: { outDir, emptyOutDir: true, }, }); ``` -------------------------------- ### Defer Page Props Source: https://github.com/mergehez/inertianetcore/blob/main/README.md Use Inertia.Defer to delay the loading of specific props until after the initial page render. ```csharp public IActionResult Profile() { return Inertia.Render("pages/Profile", new InertiaProps { ["Foo"] = "Bar", ["Posts"] = Inertia.Defer(async () { return await _context.Posts.ToListAsync(); }) }); } ``` -------------------------------- ### Perform External Redirects with Inertia.Location Source: https://context7.com/mergehez/inertianetcore/llms.txt Forces a full page visit to bypass Inertia's client-side routing. ```csharp [HttpPost("logout")] public IActionResult Logout() { // Sign out user HttpContext.SignOutAsync(); // Force full page redirect return Inertia.Location("/login"); } [HttpGet("external")] public IActionResult ExternalRedirect() { return Inertia.Location("https://external-service.com/callback"); } ``` -------------------------------- ### Enable Encrypted Browser History Source: https://context7.com/mergehez/inertianetcore/llms.txt Call Inertia.EnableEncryptHistory() for specific requests to encrypt sensitive page history. Alternatively, configure encryption globally in Program.cs. ```csharp using InertiaNetCore; // ... [HttpGet("account/settings")] public IActionResult AccountSettings() { // Enable encryption for this request Inertia.EnableEncryptHistory(); return Inertia.Render("pages/AccountSettings", new InertiaProps { ["SensitiveData"] = _accountService.GetSensitiveSettings() }); } // Or configure globally in Program.cs builder.Services.AddInertia(options => { options.EncryptHistory = true; // All pages encrypted by default }); ``` -------------------------------- ### Include Vite Bundled Assets Source: https://context7.com/mergehez/inertianetcore/llms.txt Use Vite.Input to generate script and stylesheet tags for Vite-bundled assets. This helper automatically supports Hot Module Replacement (HMR) in development environments. ```html @using InertiaNetCore @model InertiaNetCore.InertiaPage My App @await Inertia.Html(Model) @* Include main TypeScript/JavaScript entry point *@ @Vite.Input("src/app.ts") @* Or include multiple entry points *@ @Vite.Input("src/app.scss") ``` -------------------------------- ### Render Inertia Pages and Handle Forms Source: https://github.com/mergehez/inertianetcore/blob/main/README.md Use Inertia.Render to pass data to frontend components and handle form submissions with JSON payloads. ```csharp [Route("about")] public IActionResult About() { return Inertia.Render("pages/PageAbout", new InertiaProps { ["Name"] = "InertiaNetCore", ["Version"] = Assembly.GetAssembly(typeof(Inertia))?.GetName().Version?.ToString() }); } ``` ```csharp [HttpPost] public async Task Create([FromBody] Post post) { if (!ModelState.IsValid) { // The validation errors are passed automatically. return await Index(); } _context.Add(post); await _context.SaveChangesAsync(); return RedirectToAction("Index"); } ``` -------------------------------- ### Enable Inertia Middleware with UseInertia Source: https://context7.com/mergehez/inertianetcore/llms.txt Enables Inertia middleware in the request pipeline. This handles version checking and automatic asset refreshing for Inertia.js applications. ```csharp var app = builder.Build(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllers(); // Enable Inertia middleware app.UseInertia(); app.Run(); ``` -------------------------------- ### Render Inertia Page with SSR Support Source: https://context7.com/mergehez/inertianetcore/llms.txt Use Inertia.Head and Inertia.Html in your layout to enable server-side rendering. This improves SEO and initial load performance by rendering content on the server. ```html @using InertiaNetCore @model InertiaNetCore.InertiaPage My SSR App @* Render SSR head content (meta tags, etc.) *@ @await Inertia.Head(Model) @* Render SSR body content or client-side hydration div *@ @await Inertia.Html(Model) @Vite.Input("src/app.ts") ``` -------------------------------- ### Always Include Props for Fresh Data Source: https://context7.com/mergehez/inertianetcore/llms.txt Utilize Inertia.Always to ensure props are re-evaluated on every request, including partial reloads. This is useful for data that must always be up-to-date. ```csharp using InertiaNetCore; // ... [HttpGet] public IActionResult Dashboard() { return Inertia.Render("pages/Dashboard", new InertiaProps { ["User"] = _userService.GetCurrentUser(), // Always fresh - included in every request ["UnreadCount"] = Inertia.Always(() => _notificationService.GetUnreadCount()), // Async always prop ["LiveStats"] = Inertia.Always(async () => { return await _statsService.GetLiveMetricsAsync(); }) }); } ``` -------------------------------- ### Handle Form Submissions with Validation in ASP.NET Core Source: https://context7.com/mergehez/inertianetcore/llms.txt Use [FromBody] for JSON requests and return Inertia.Back() to pass validation errors to the frontend. Flash messages can be attached to redirects or back responses. ```csharp public class PostsController : Controller { private readonly AppDbContext _context; public PostsController(AppDbContext context) => _context = context; [HttpGet("posts")] public async Task Index() { var posts = await _context.Posts.ToListAsync(); return Inertia.Render("pages/Posts/Index", new InertiaProps { ["Posts"] = posts }); } [HttpGet("posts/create")] public IActionResult Create() { return Inertia.Render("pages/Posts/Create"); } // IMPORTANT: Use [FromBody] for JSON request data [HttpPost("posts")] public async Task Store([FromBody] CreatePostRequest request) { if (!ModelState.IsValid) { // Validation errors automatically passed to frontend return Inertia.Back(); } var post = new Post { Title = request.Title, Content = request.Content, CreatedAt = DateTime.UtcNow }; _context.Posts.Add(post); await _context.SaveChangesAsync(); Inertia.Flash("success", "Post created successfully!"); return RedirectToAction("Index"); } [HttpPut("posts/{id}")] public async Task Update(int id, [FromBody] UpdatePostRequest request) { var post = await _context.Posts.FindAsync(id); if (post == null) { return Inertia.Back().WithFlash("error", "Post not found."); } if (!ModelState.IsValid) { return Inertia.Back(); } post.Title = request.Title; post.Content = request.Content; await _context.SaveChangesAsync(); return Inertia.Back().WithFlash("success", "Post updated!"); } [HttpDelete("posts/{id}")] public async Task Destroy(int id) { var post = await _context.Posts.FindAsync(id); if (post != null) { _context.Posts.Remove(post); await _context.SaveChangesAsync(); } Inertia.Flash("success", "Post deleted."); return RedirectToAction("Index"); } } ``` -------------------------------- ### Render Inertia Page Components with Inertia.Render Source: https://context7.com/mergehez/inertianetcore/llms.txt Renders an Inertia page component with specified props. Returns an IActionResult for initial page loads and subsequent Inertia requests. ```csharp using InertiaNetCore; using InertiaNetCore.Models; using Microsoft.AspNetCore.Mvc; [Route("/")] public class HomeController : Controller { [HttpGet] public IActionResult Index() { return Inertia.Render("pages/PageIndex", new InertiaProps { ["Title"] = "Welcome to My App", ["Users"] = new[] { "Alice", "Bob", "Charlie" }, ["Stats"] = new { Visits = 1234, Signups = 56 } }); } [Route("about")] public IActionResult About() { return Inertia.Render("pages/PageAbout", new InertiaProps { ["Name"] = "InertiaNetCore", ["Version"] = "0.0.15" }); } // Using Dictionary instead of InertiaProps [Route("profile")] public IActionResult Profile() { return Inertia.Render("pages/Profile", new Dictionary { ["User"] = new { Name = "John", Email = "john@example.com" } }); } } ``` -------------------------------- ### Lazy-Load Props with Inertia.Lazy Source: https://context7.com/mergehez/inertianetcore/llms.txt Defers prop evaluation until explicitly requested via partial reloads. ```csharp [HttpGet] public IActionResult Index() { return Inertia.Render("pages/Dashboard", new InertiaProps { ["User"] = _userService.GetCurrentUser(), // Sync lazy prop - only loaded on partial reload ["RecentActivity"] = Inertia.Lazy(() => _activityService.GetRecent()), // Async lazy prop with delay ["DetailedStats"] = Inertia.Lazy(async () => { await Task.Delay(500); // Simulate expensive operation return await _statsService.GetDetailedAsync(); }) }); } // Frontend: Request lazy prop via partial reload // router.reload({ only: ['RecentActivity'] }) ``` -------------------------------- ### Set Flash Messages with Inertia.Flash Source: https://context7.com/mergehez/inertianetcore/llms.txt Persists messages across redirects for immediate display in the next response. ```csharp [Route("users")] public class UsersController : Controller { [HttpDelete("{id:int}")] public async Task Destroy(int id) { var user = await _userService.FindAsync(id); if (user == null) { Inertia.Flash("error", "User not found."); return RedirectToAction("Index"); } await _userService.DeleteAsync(id); // Set flash message before redirect Inertia.Flash("success", "User deleted successfully."); return RedirectToAction("Index"); } } ``` -------------------------------- ### Enable React HMR with Vite Source: https://context7.com/mergehez/inertianetcore/llms.txt Incorporate Vite.ReactRefresh() into your HTML layout to enable React's Hot Module Replacement. This script is active only in development mode. ```html @using InertiaNetCore @model InertiaNetCore.InertiaPage My React App @* React Refresh for HMR (only active in dev mode) *@ @Vite.ReactRefresh() @await Inertia.Html(Model) @Vite.Input("src/main.tsx") ``` -------------------------------- ### Detect Inertia Requests with IsInertiaRequest Source: https://context7.com/mergehez/inertianetcore/llms.txt Use the IsInertiaRequest extension method in middleware or controllers to identify client-side navigation. ```csharp app.Use(async (context, next) => { if (context.IsInertiaRequest()) { // Handle Inertia-specific logic Console.WriteLine("Inertia request detected"); } await next(); }); // Or in a controller public IActionResult Index() { if (HttpContext.IsInertiaRequest()) { // Partial response logic } return Inertia.Render("pages/Index"); } ``` -------------------------------- ### Merge Props for Infinite Scrolling Source: https://context7.com/mergehez/inertianetcore/llms.txt Use Inertia.Merge to append new data to existing props, ideal for infinite scrolling and pagination. Frontend requests should specify 'only' to reload specific props. ```csharp using InertiaNetCore; // ... [HttpGet] public IActionResult Users(int page = 1, int perPage = 10) { return Inertia.Render("pages/Users", new InertiaProps { ["Filters"] = new { Page = page, PerPage = perPage }, // Results will merge with existing data on subsequent loads ["Results"] = Inertia.Merge(async () => { return await _userService.GetPaginatedAsync(page, perPage); }) }); } ``` -------------------------------- ### Merge Page Props Source: https://github.com/mergehez/inertianetcore/blob/main/README.md Use Inertia.Merge to prevent props from being overwritten during page reloads, useful for pagination. ```csharp public IActionResult Users(int page, int perPage) { return Inertia.Render("pages/Users", new InertiaProps { ["Results"] = Inertia.Merge(async () { return await GetPaginatedUsers(page, perPage); }) }); } ``` -------------------------------- ### Clear Encrypted Browser History Source: https://context7.com/mergehez/inertianetcore/llms.txt Use Inertia.ClearHistory() to remove encrypted history state, typically called before logging out or switching users to ensure data security. ```csharp using InertiaNetCore; // ... [HttpPost("logout")] public IActionResult Logout() { // Clear all encrypted history before logout Inertia.ClearHistory(); HttpContext.SignOutAsync(); return Inertia.Location("/login"); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.