{"id":"44fc38ae-9413-4cfd-8b6d-b19964017663","shortId":"T29xnD","kind":"skill","title":"litestar-inertia","tagline":"Auto-activate for litestar_vite.inertia, InertiaConfig, component= route handlers, @inertia, @inertiajs/react, @inertiajs/vue3, @inertiajs/svelte, createInertiaApp, useForm, usePage, Link, router, or resources/js/pages. Use when wiring Inertia.js with Litestar and litestar-vite f","description":"# Litestar + Inertia.js Integration\n\n`litestar-inertia` is the four-library story:\n\n| Layer | Library | Role |\n| --- | --- | --- |\n| Client SPA | [`@inertiajs/react`](https://inertiajs.com) / `@inertiajs/vue3` / `@inertiajs/svelte` | Page resolution, forms, navigation, shared data access |\n| Frontend build | [`vite`](https://vitejs.dev) | Bundling, HMR, dev server, production build |\n| Python bridge | [`litestar-vite`](../litestar-vite/SKILL.md) | `VitePlugin` + `InertiaConfig`, asset manifest, type generation, page-props codec |\n| Server framework | [`litestar`](../litestar/SKILL.md) | Routes, Controllers, Guards, DI, DTOs — returning Inertia responses |\n\nYou can't skip any of these. Using Inertia with Litestar requires all four, and the skills form a chain: Litestar routes produce page data → `ViteConfig.inertia` configures the Inertia response layer → Vite-served client bundle mounts the page component → Inertia client takes over for subsequent navigations.\n\nThis skill covers that integration end-to-end. For anything that's purely about one layer (e.g., Vite config internals) see the corresponding sibling skill.\n\n## When this skill activates\n\n- Python files importing `litestar_vite.inertia`, `InertiaConfig`, or route handlers with `component=`\n- `*.tsx` / `*.vue` / `*.svelte` files importing from `@inertiajs/*`\n- `createInertiaApp({ resolve, setup })` in a frontend entrypoint\n- A `resources/` or `resources/js/pages/` directory alongside a `src/py/` — classic litestar-vite + Inertia layout\n- `inertia.config.ts` or an `InertiaConfig` invocation in `vite.config.ts`\n- User asks about \"building an SPA with a Python backend\", \"server-driven React/Vue\", \"form validation errors from Python\", \"shared auth data across pages\"\n\n## Code Style Rules\n\n- **PEP 604 unions, `from __future__ import annotations`** in consumer Python modules — standard Litestar rules apply\n- **TypeScript typed pages** — generate page-props types via `litestar-vite`'s TypeGen, never hand-roll\n- **Forms via `useForm`** — never a plain `<form onSubmit>`. `useForm` handles CSRF, errors, submission state, and navigation in one call\n- **Shared data for auth + flash**, never page-specific. Static page props go in `InertiaConfig.extra_static_page_props`; session-backed props go in `extra_session_page_props`; request-time flashes use `share(request, ...)`.\n- **camelCase on the wire** — Python msgspec Structs use `Meta(rename=\"camel\")`, JS consumes `camelCase` directly\n- **Partial reloads** over full-page reloads when only a subset of props changes (`router.reload({ only: ['notifications'] })`)\n- **Lazy props** for expensive-to-compute page data the user may not need on first paint\n\n## Quick Reference\n\n### Backend — Python route returning an Inertia page\n\n```python\nfrom __future__ import annotations\n\nfrom litestar import Controller, get\n\nfrom app.domain.accounts.guards import requires_active_user\nfrom app.domain.dashboard.schemas import Dashboard\n\n\nclass DashboardController(Controller):\n    path = \"/dashboard\"\n    guards = [requires_active_user]\n\n    @get(\"/\", component=\"dashboard/Index\")\n    async def index(self, dashboard_service) -> Dashboard:\n        return await dashboard_service.get_for_current_user()\n```\n\n→ See [references/litestar_integration.md](references/litestar_integration.md)\n\n### Client — page component (React)\n\n```tsx\n// resources/js/pages/dashboard/Index.tsx\nimport { usePage, Head } from \"@inertiajs/react\";\nimport type { Dashboard } from \"@/types/generated\";   // TypeGen output\n\nexport default function DashboardIndex() {\n  const { dashboard } = usePage<{ dashboard: Dashboard }>().props;\n\n  return (\n    <>\n      <Head title=\"Dashboard\" />\n      <h1>Welcome, {dashboard.user.name}</h1>\n      <p>Your workspace has {dashboard.workspaceCount} projects.</p>\n    </>\n  );\n}\n```\n\n→ See [references/protocol.md](references/protocol.md)\n\n### App wiring — VitePlugin owns the Inertia bridge\n\n```python\nfrom __future__ import annotations\n\nfrom litestar import Litestar\nfrom litestar.middleware.session.client_side import CookieBackendConfig\nfrom litestar_granian import GranianPlugin\nfrom litestar_vite import InertiaConfig, PathConfig, TypeGenConfig, ViteConfig, VitePlugin\n\nfrom app.domain.accounts.schemas import CurrentUser\nfrom app.lib.settings import get_settings\n\n\nsettings = get_settings()\nsession_backend = CookieBackendConfig(secret=settings.secret_key.encode(\"utf-8\"))\nvite = VitePlugin(\n    config=ViteConfig(\n        mode=\"hybrid\",\n        dev_mode=settings.debug,\n        paths=PathConfig(\n            root=settings.base_dir,\n            resource_dir=\"resources\",\n            bundle_dir=\"public\",\n        ),\n        inertia=InertiaConfig(\n            root_template=\"index.html\",\n            extra_static_page_props={\"appName\": settings.app_name},\n            extra_session_page_props={\"currentUser\": CurrentUser},\n        ),\n        types=TypeGenConfig(output=\"resources/generated\"),\n    )\n)\n\napp = Litestar(\n    route_handlers=[DashboardController, ...],\n    plugins=[GranianPlugin(), vite],\n    middleware=[session_backend.middleware],\n)\n```\n\n→ See [references/litestar_integration.md](references/litestar_integration.md) for full wiring\n\n### Forms — `useForm` with Litestar validation errors\n\n```tsx\nimport { useForm } from \"@inertiajs/react\";\n\nexport default function CreateProject() {\n  const { data, setData, post, processing, errors } = useForm({\n    name: \"\",\n    description: \"\",\n  });\n\n  return (\n    <form onSubmit={(e) => { e.preventDefault(); post(\"/projects\"); }}>\n      <input value={data.name} onChange={(e) => setData(\"name\", e.target.value)} />\n      {errors.name && <div className=\"error\">{errors.name}</div>}\n\n      <textarea value={data.description} onChange={(e) => setData(\"description\", e.target.value)} />\n      {errors.description && <div className=\"error\">{errors.description}</div>}\n\n      <button type=\"submit\" disabled={processing}>Create</button>\n    </form>\n  );\n}\n```\n\nOn the Python side, raising a `ValidationException` with a `dict` of field errors auto-maps into `errors` on the client — no manual serialization.\n\n### Partial reloads — only re-fetch what changed\n\n```tsx\nimport { router } from \"@inertiajs/react\";\n\n// After a background task finishes, reload only notifications:\nrouter.reload({ only: [\"notifications\"] });\n```\n\n### Lazy props — defer expensive data\n\n```python\nfrom litestar import get\nfrom litestar_vite.inertia import lazy\n\n@get(\"/reports\", component=\"reports/Index\")\nasync def reports_page(self, reports_service) -> dict:\n    return {\n        \"summary\": await reports_service.summary(),            # eager\n        \"fullExport\": lazy(lambda: reports_service.export()),  # deferred\n    }\n```\n\nClient fetches `fullExport` only on `router.reload({ only: [\"fullExport\"] })`.\n\n## Workflow\n\n### Step 1 — Wire the bridge\n\nRegister `GranianPlugin` and one `VitePlugin(config=ViteConfig(inertia=InertiaConfig(...)))`. Add session middleware. Do not register a second Inertia plugin in normal app scaffolds; `VitePlugin` reads `ViteConfig.inertia` and configures the Inertia bridge.\n\n### Step 2 — Define shared props\n\nPut static values in `InertiaConfig.extra_static_page_props`. Put session-backed values in `extra_session_page_props` so the integration pulls them from `request.session`. For request-time flash/auth additions, call `share(request, key, value)` before returning an Inertia response. These are available on every page via `usePage().props` without threading them through each handler.\n\n### Step 3 — Set up the client entrypoint\n\n`resources/js/app.tsx` (React) or equivalent: `createInertiaApp({ resolve: (name) => resolvePageComponent(name, ...), setup: ({ el, App, props }) => createRoot(el).render(<App {...props} />) })`.\n\n### Step 4 — Build page components\n\nOne `.tsx` / `.vue` / `.svelte` file per route, keyed by name. `@get(..., component=\"path/Name\")` on the Python handler maps to `resources/js/pages/path/Name.tsx`.\n\n### Step 5 — Generate types\n\n`litestar assets generate-types` (from `litestar-vite`) reads your Python msgspec/DTO schemas and emits TypeScript types the page components consume directly.\n\n### Step 6 — Validate\n\n- `/` returns `text/html` (full initial render) on first visit\n- Subsequent navigations return `application/json` with Inertia envelope (`X-Inertia: true`)\n- DevTools Network tab shows `X-Inertia-*` response headers\n- `useForm().post()` with invalid data returns 422 + `errors` populated\n\n## Guardrails\n\n- **Don't mix Inertia and plain JSON API routes in the same app surface** — pick one per domain. Mixing confuses auth, CSRF, and response shape expectations. If you need both, use separate route prefixes (`/api/*` for JSON, `/dashboard/*` for Inertia).\n- **CSRF is enabled by default in Litestar-Vite's Inertia integration** — don't disable unless you know what you're breaking. `useForm` handles the token transparently.\n- **Shared props must be cheap** — session props are read on every page request. Cache user lookup; don't hit the DB for feature flags; use Redis for session state.\n- **Version strings matter** — Inertia tracks an asset version; mismatched versions force a full page reload. Let `litestar-vite` generate the version hash; don't hand-roll.\n- **No mixed-framework pages** — React + Vue in the same app breaks Inertia's resolver. Pick one adapter per project.\n- **Deep-link routes need real URLs** — every Inertia page should have a Litestar route returning it. SPA-only client routes (React Router inside an Inertia page) exist but are an escape hatch.\n- **Don't forget the root template** — `InertiaConfig.root_template` points at the template that mounts the SPA. Default is `index.html`; Jinja-backed Inertia apps set a Litestar `TemplateConfig` as well.\n\n## Validation Checkpoint\n\nBefore shipping an Inertia-integrated Litestar app:\n\n- [ ] `ViteConfig.inertia` configured with `InertiaConfig(...)`\n- [ ] One `VitePlugin` registered for Vite + Inertia\n- [ ] Session middleware registered\n- [ ] Static/session/request-time shared props have consistent shape across handlers\n- [ ] Page components resolve via the resolver function (one place of truth for path→component mapping)\n- [ ] TypeScript page-props types generated via `litestar assets generate-types`\n- [ ] Forms use `useForm`, not bare `<form>`\n- [ ] 422 responses from Litestar include `errors` that the client reads\n- [ ] CSRF/session data is exposed through Inertia shared props and `useForm` picks it up automatically\n- [ ] `dev_mode` toggles correctly between dev (Vite HMR) and prod (manifest-resolved assets)\n- [ ] Production build (`litestar assets build`) emits `public/manifest.json` + hashed bundles\n\n## Example — Authenticated dashboard with forms + partial reload\n\n```python\n# app/domain/projects/controllers.py\nfrom __future__ import annotations\n\nfrom litestar import Controller, get, post\nfrom litestar.exceptions import ValidationException\nfrom litestar_vite.inertia import back\n\nfrom app.domain.accounts.guards import requires_active_user\nfrom app.domain.projects.schemas import Project, ProjectCreate\nfrom app.domain.projects.services import ProjectService\n\n\nclass ProjectsController(Controller):\n    path = \"/projects\"\n    guards = [requires_active_user]\n\n    @get(\"/\", component=\"projects/Index\")\n    async def index(self, projects_service: ProjectService, request) -> dict:\n        return {\n            \"projects\": await projects_service.list_for_user(request.user.id),\n        }\n\n    @post(\"/\")\n    async def create(\n        self, data: ProjectCreate, projects_service: ProjectService, request,\n    ) -> None:\n        # Validation\n        if await projects_service.exists(name=data.name, owner_id=request.user.id):\n            raise ValidationException(extra={\"name\": \"You already have a project with this name.\"})\n\n        await projects_service.create(data.to_dict(), owner_id=request.user.id)\n        # `back()` redirects Inertia back to the previous page with flash data intact\n        return back()\n```\n\n```tsx\n// resources/js/pages/projects/Index.tsx\nimport { useForm, usePage, router } from \"@inertiajs/react\";\nimport type { Project } from \"@/types/generated\";\n\nexport default function ProjectsIndex() {\n  const { projects, flash } = usePage<{ projects: Project[]; flash: { success?: string } }>().props;\n\n  const { data, setData, post, processing, errors, reset } = useForm({ name: \"\", description: \"\" });\n\n  const onSubmit = (e: React.FormEvent) => {\n    e.preventDefault();\n    post(\"/projects\", { onSuccess: () => reset() });\n  };\n\n  return (\n    <>\n      {flash.success && <div className=\"flash\">{flash.success}</div>}\n\n      <form onSubmit={onSubmit}>\n        <input value={data.name} onChange={(e) => setData(\"name\", e.target.value)} placeholder=\"Project name\" />\n        {errors.name && <div className=\"error\">{errors.name}</div>}\n        <textarea value={data.description} onChange={(e) => setData(\"description\", e.target.value)} />\n        <button disabled={processing}>Create</button>\n      </form>\n\n      <button onClick={() => router.reload({ only: [\"projects\"] })}>Refresh</button>\n\n      <ul>\n        {projects.map((p) => <li key={p.id}>{p.name}</li>)}\n      </ul>\n    </>\n  );\n}\n```\n\n## References Index\n\n- **[Inertia Protocol & Client](references/protocol.md)** — Protocol v2, request/response shape, React/Vue/Svelte adapter setup, `useForm`, `usePage`, `router`, partial reloads, lazy props, SSR\n- **[Litestar Backend Integration](references/litestar_integration.md)** — `InertiaConfig`, `component=` route handlers, shared props, `back()`, validation errors, type generation, SSR server\n\n## Cross-Skill References\n\n- **[`../litestar-vite/SKILL.md`](../litestar-vite/SKILL.md)** — Vite plugin config, `VitePlugin`, asset manifest, TypeGen pipeline, HMR (the backbone Inertia sits on)\n- **[`../litestar/SKILL.md`](../litestar/SKILL.md)** — Controllers, Guards, DI, DTO patterns (the request handling layer)\n- **[`../advanced-alchemy/SKILL.md`](../advanced-alchemy/SKILL.md)** — Data services that produce page props\n- **[`../msgspec/SKILL.md`](../msgspec/SKILL.md)** — Struct definitions that TypeGen consumes\n\n## Canonical Reference Implementation\n\nThe canonical Litestar + Inertia stack lives at [`litestar-fullstack-inertia`](https://github.com/litestar-org/litestar-fullstack-inertia). When in doubt about wiring or file layout, mirror it.\n\n## Official References\n\n- Inertia.js v2 docs: <https://inertiajs.com/docs/v2>\n- Upgrade guide v1 → v2: <https://inertiajs.com/docs/v2/getting-started/upgrade-guide>\n- Client-side setup: <https://inertiajs.com/docs/v2/installation/client-side-setup>\n- Release notes: <https://github.com/inertiajs/inertia/releases>\n- `litestar-vite` Inertia docs: <https://litestar-org.github.io/litestar-vite/inertia/>\n- `litestar-vite` Inertia API: <https://litestar-org.github.io/litestar-vite/reference/inertia/>\n\n## Shared Styleguide Baseline\n\n- [General Principles](../litestar-styleguide/references/general.md)\n- [Python](../litestar-styleguide/references/python.md)\n- [TypeScript](../litestar-styleguide/references/typescript.md)\n- [Litestar](../litestar-styleguide/references/litestar.md)\n\nKeep this skill focused on the Litestar ↔ Vite ↔ Inertia integration surface. Framework-agnostic React/Vue/Svelte patterns belong in the respective framework skills (if we ever port them) or `inertiajs.com` docs.","tags":["litestar","inertia","skills","litestar-org","advanced-alchemy","agent-skills","agentskills","ai-agents","claude-code-plugin","claude-code-skills","gemini-cli-extension","htmx"],"capabilities":["skill","source-litestar-org","skill-litestar-inertia","topic-advanced-alchemy","topic-agent-skills","topic-agentskills","topic-ai-agents","topic-claude-code-plugin","topic-claude-code-skills","topic-gemini-cli-extension","topic-htmx","topic-inertia","topic-litestar","topic-mcp","topic-python"],"categories":["litestar-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/litestar-org/litestar-skills/litestar-inertia","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add litestar-org/litestar-skills","source_repo":"https://github.com/litestar-org/litestar-skills","install_from":"skills.sh"}},"qualityScore":"0.453","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 7 github stars · SKILL.md body (15,313 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:13:54.137Z","embedding":null,"createdAt":"2026-05-18T13:20:57.721Z","updatedAt":"2026-05-18T19:13:54.137Z","lastSeenAt":"2026-05-18T19:13:54.137Z","tsv":"'-8':533 '/advanced-alchemy/skill.md':1557,1558 '/api':991 '/dashboard':417,994 '/docs/v2':1606 '/docs/v2/getting-started/upgrade-guide':1613 '/docs/v2/installation/client-side-setup':1620 '/inertiajs/inertia/releases':1625 '/litestar-org/litestar-fullstack-inertia).':1588 '/litestar-styleguide/references/general.md':1647 '/litestar-styleguide/references/litestar.md':1653 '/litestar-styleguide/references/python.md':1649 '/litestar-styleguide/references/typescript.md':1651 '/litestar-vite/inertia/':1633 '/litestar-vite/reference/inertia/':1641 '/litestar-vite/skill.md':78,1530,1531 '/litestar/skill.md':92,1546,1547 '/msgspec/skill.md':1565,1566 '/projects':622,1321,1442 '/reports':712 '/types/generated':456,1411 '1':743 '2':779 '3':840 '4':865 '422':953,1228 '5':890 '6':917 '604':251 'access':62 'across':245,1194 'activ':6,177,407,420,1306,1324 'adapt':1098,1499 'add':756 'addit':813 'agnost':1667 'alongsid':207 'alreadi':1371 'annot':256,397,491,1287 'anyth':158 'api':964,1638 'app':480,576,768,857,862,969,1091,1158,1174 'app.domain.accounts.guards':404,1303 'app.domain.accounts.schemas':516 'app.domain.dashboard.schemas':410 'app.domain.projects.schemas':1309 'app.domain.projects.services':1314 'app.lib.settings':520 'app/domain/projects/controllers.py':1283 'appli':264 'application/json':930 'appnam':563 'ask':224 'asset':81,894,1059,1219,1265,1269,1536 'async':425,715,1329,1346 'auth':243,303,977 'authent':1276 'auto':5,663 'auto-activ':4 'auto-map':662 'automat':1251 'avail':826 'await':433,725,1340,1359,1378 'back':320,794,1156,1301,1385,1388,1398,1519 'backbon':1542 'backend':232,386,528,1510 'background':688 'bare':1227 'baselin':1644 'belong':1670 'break':1018,1092 'bridg':74,486,746,777 'build':64,72,226,866,1267,1270 'bundl':67,136,551,1274 'button':643,1472,1476 'cach':1037 'call':299,814 'camel':345 'camelcas':335,348 'canon':1572,1576 'chain':120 'chang':363,680 'cheap':1028 'checkpoint':1166 'class':413,1317 'classic':210 'client':50,135,142,441,669,733,844,1121,1236,1492,1615 'client-sid':1614 'code':247 'codec':88 'compon':10,140,187,423,443,713,868,880,913,1197,1209,1327,1514 'comput':373 'config':167,536,752,1534 'configur':127,774,1176 'confus':976 'consist':1192 'const':463,607,1416,1426,1436 'consum':258,347,914,1571 'control':94,401,415,1291,1319,1548 'cookiebackendconfig':500,529 'correct':1255 'correspond':171 'cover':150 'creat':648,1348,1475 'createinertiaapp':17,195,850 'createproject':606 'createroot':859 'cross':1527 'cross-skil':1526 'csrf':291,978,997 'csrf/session':1238 'current':436 'currentus':518,570,571 'dashboard':412,429,431,454,464,466,467,1277 'dashboard.user.name':471 'dashboard.workspacecount':475 'dashboard/index':424 'dashboard_service.get':434 'dashboardcontrol':414,580 'dashboardindex':462 'data':61,125,244,301,375,608,701,951,1239,1350,1395,1427,1559 'data.description':635,1466 'data.name':625,1362,1453 'data.to':1380 'db':1044 'deep':1102 'deep-link':1101 'def':426,716,1330,1347 'default':460,604,1001,1151,1413 'defer':699,732 'defin':780 'definit':1568 'descript':615,639,1435,1470 'dev':69,540,1252,1257 'devtool':938 'di':96,1550 'dict':658,722,1337,1381 'dir':547,549,552 'direct':349,915 'directori':206 'disabl':646,1011,1473 'doc':1603,1630,1683 'domain':974 'doubt':1591 'driven':235 'dto':1551 'dtos':97 'e':619,627,637,1438,1455,1468 'e.g':165 'e.preventdefault':620,1440 'e.target.value':630,640,1458,1471 'eager':727 'el':856,860 'emit':908,1271 'enabl':999 'end':154,156 'end-to-end':153 'entrypoint':201,845 'envelop':933 'equival':849 'error':239,292,597,612,661,666,954,1233,1431,1521 'errors.description':641,642 'errors.name':631,632,1462,1463 'escap':1133 'ever':1678 'everi':828,1034,1108 'exampl':1275 'exist':1129 'expect':982 'expens':371,700 'expensive-to-comput':370 'export':459,603,1412 'expos':1241 'extra':324,559,566,797,1368 'f':34 'featur':1046 'fetch':678,734 'field':660 'file':179,191,873,1595 'finish':690 'first':382,925 'flag':1047 'flash':304,331,1394,1418,1422 'flash.success':1446,1447 'flash/auth':812 'focus':1657 'forc':1063 'forget':1137 'form':58,118,237,283,592,617,1223,1279,1448 'four':44,114 'four-librari':43 'framework':90,1084,1666,1674 'framework-agnost':1665 'frontend':63,200 'full':354,590,921,1065 'full-pag':353 'fullexport':728,735,740 'fullstack':1584 'function':461,605,1202,1414 'futur':254,395,489,1285 'general':1645 'generat':84,268,891,896,1072,1216,1221,1523 'generate-typ':895,1220 'get':402,422,522,525,706,711,879,1292,1326 'github.com':1587,1624 'github.com/inertiajs/inertia/releases':1623 'github.com/litestar-org/litestar-fullstack-inertia).':1586 'go':312,322 'granian':503 'granianplugin':505,582,748 'guard':95,418,1322,1549 'guardrail':956 'guid':1608 'hand':281,1079 'hand-rol':280,1078 'handl':290,1020,1555 'handler':12,185,579,838,885,1195,1516 'hash':1075,1273 'hatch':1134 'head':449 'header':946 'hit':1042 'hmr':68,1259,1540 'hybrid':539 'id':1364,1383 'implement':1574 'import':180,192,255,396,400,405,411,447,452,490,494,499,504,509,517,521,599,682,705,709,1286,1290,1296,1300,1304,1310,1315,1401,1407 'includ':1232 'index':427,1331,1489 'index.html':558,1153 'inertia':3,13,40,99,109,129,141,214,391,485,554,754,764,776,822,932,936,944,960,996,1007,1056,1093,1109,1127,1157,1171,1184,1243,1387,1490,1543,1578,1585,1629,1637,1662 'inertia-integr':1170 'inertia.config.ts':216 'inertia.js':27,36,1601 'inertiaconfig':9,80,182,219,510,555,755,1178,1513 'inertiaconfig.extra':314,787 'inertiaconfig.root':1141 'inertiaj':194 'inertiajs.com':53,1605,1612,1619,1682 'inertiajs.com/docs/v2':1604 'inertiajs.com/docs/v2/getting-started/upgrade-guide':1611 'inertiajs.com/docs/v2/installation/client-side-setup':1618 'inertiajs/react':14,52,451,602,685,1406 'inertiajs/svelte':16,55 'inertiajs/vue3':15,54 'initi':922 'input':623,1451 'insid':1125 'intact':1396 'integr':37,152,803,1008,1172,1511,1663 'intern':168 'invalid':950 'invoc':220 'jinja':1155 'jinja-back':1154 'js':346 'json':963,993 'keep':1654 'key':817,876,1485 'know':1014 'lambda':730 'layer':47,131,164,1556 'layout':215,1596 'lazi':367,697,710,729,1506 'let':1068 'li':1484 'librari':45,48 'link':20,1103 'litestar':2,29,32,35,39,76,91,111,121,212,262,275,399,493,495,502,507,577,595,704,893,900,1004,1070,1114,1161,1173,1218,1231,1268,1289,1509,1577,1583,1627,1635,1652,1660 'litestar-fullstack-inertia':1582 'litestar-inertia':1,38 'litestar-org.github.io':1632,1640 'litestar-org.github.io/litestar-vite/inertia/':1631 'litestar-org.github.io/litestar-vite/reference/inertia/':1639 'litestar-vit':31,75,211,274,899,1003,1069,1626,1634 'litestar.exceptions':1295 'litestar.middleware.session.client':497 'litestar_vite.inertia':8,181,708,1299 'live':1580 'lookup':1039 'manifest':82,1263,1537 'manifest-resolv':1262 'manual':671 'map':664,886,1210 'matter':1055 'may':378 'meta':343 'middlewar':584,758,1186 'mirror':1597 'mismatch':1061 'mix':959,975,1083 'mixed-framework':1082 'mode':538,541,1253 'modul':260 'mount':137,1148 'msgspec':340 'msgspec/dto':905 'must':1026 'name':565,614,629,852,854,878,1361,1369,1377,1434,1457,1461 'navig':59,147,296,928 'need':380,985,1105 'network':939 'never':279,286,305 'none':1356 'normal':767 'note':1622 'notif':366,693,696 'offici':1599 'onchang':626,636,1454,1467 'onclick':1477 'one':163,298,750,869,972,1097,1179,1203 'onsubmit':618,1437,1449,1450 'onsuccess':1443 'output':458,574 'own':483 'owner':1363,1382 'p':1483 'p.id':1486 'p.name':1487 'page':56,86,124,139,246,267,270,307,310,316,326,355,374,392,442,561,568,718,789,799,829,867,912,1035,1066,1085,1110,1128,1196,1213,1392,1563 'page-prop':85,269,1212 'page-specif':306 'paint':383 'partial':350,673,1280,1504 'path':416,543,1208,1320 'path/name':881 'pathconfig':511,544 'pattern':1552,1669 'pep':250 'per':874,973,1099 'pick':971,1096,1248 'pipelin':1539 'place':1204 'placehold':1459 'plain':288,962 'plugin':581,765,1533 'point':1143 'popul':955 'port':1679 'post':610,621,948,1293,1345,1429,1441 'prefix':990 'previous':1391 'principl':1646 'process':611,647,1430,1474 'prod':1261 'produc':123,1562 'product':71,1266 'project':476,1100,1311,1333,1339,1352,1374,1409,1417,1420,1421,1460,1480 'projectcr':1312,1351 'projects.map':1482 'projects/index':1328 'projects_service.create':1379 'projects_service.exists':1360 'projects_service.list':1341 'projectscontrol':1318 'projectservic':1316,1335,1354 'projectsindex':1415 'prop':87,271,311,317,321,327,362,368,468,562,569,698,782,790,800,832,858,863,1025,1030,1190,1214,1245,1425,1507,1518,1564 'protocol':1491,1494 'public':553 'public/manifest.json':1272 'pull':804 'pure':161 'put':783,791 'python':73,178,231,241,259,339,387,393,487,651,702,884,904,1282,1648 'quick':384 'rais':653,1366 're':677,1017 're-fetch':676 'react':444,847,1086,1123 'react.formevent':1439 'react/vue':236 'react/vue/svelte':1498,1668 'read':771,902,1032,1237 'real':1106 'redi':1049 'redirect':1386 'refer':385,1488,1529,1573,1600 'references/litestar_integration.md':439,440,587,588,1512 'references/protocol.md':478,479,1493 'refresh':1481 'regist':747,761,1181,1187 'releas':1621 'reload':351,356,674,691,1067,1281,1505 'renam':344 'render':861,923 'report':717,720 'reports/index':714 'reports_service.export':731 'reports_service.summary':726 'request':329,334,810,816,1036,1336,1355,1554 'request-tim':328,809 'request.session':807 'request.user.id':1344,1365,1384 'request/response':1496 'requir':112,406,419,1305,1323 'reset':1432,1444 'resolut':57 'resolv':196,851,1095,1198,1201,1264 'resolvepagecompon':853 'resourc':203,548,550 'resources/generated':575 'resources/js/app.tsx':846 'resources/js/pages':23,205 'resources/js/pages/dashboard/index.tsx':446 'resources/js/pages/path/name.tsx':888 'resources/js/pages/projects/index.tsx':1400 'respect':1673 'respons':100,130,823,945,980,1229 'return':98,389,432,469,616,723,820,919,929,952,1116,1338,1397,1445 'role':49 'roll':282,1080 'root':545,556,1139 'rout':11,93,122,184,388,578,875,965,989,1104,1115,1122,1515 'router':21,683,1124,1404,1503 'router.reload':364,694,738,1478 'rule':249,263 'scaffold':769 'schema':906 'second':763 'secret':530 'see':169,438,477,586 'self':428,719,1332,1349 'separ':988 'serial':672 'serv':134 'server':70,89,234,1525 'server-driven':233 'servic':430,721,1334,1353,1560 'session':319,325,527,567,757,793,798,1029,1051,1185 'session-back':318,792 'session_backend.middleware':585 'set':523,524,526,841,1159 'setdata':609,628,638,1428,1456,1469 'settings.app':564 'settings.base':546 'settings.debug':542 'settings.secret_key.encode':531 'setup':197,855,1500,1617 'shape':981,1193,1497 'share':60,242,300,333,781,815,1024,1189,1244,1517,1642 'ship':1168 'show':941 'sibl':172 'side':498,652,1616 'sit':1544 'skill':117,149,173,176,1528,1656,1675 'skill-litestar-inertia' 'skip':104 'source-litestar-org' 'spa':51,228,1119,1150 'spa-on':1118 'specif':308 'src/py':209 'ssr':1508,1524 'stack':1579 'standard':261 'state':294,1052 'static':309,315,560,784,788 'static/session/request-time':1188 'step':742,778,839,864,889,916 'stori':46 'string':1054,1424 'struct':341,1567 'style':248 'styleguid':1643 'submiss':293 'submit':645 'subsequ':146,927 'subset':360 'success':1423 'summari':724 'surfac':970,1664 'svelt':190,872 'tab':940 'take':143 'task':689 'templat':557,1140,1142,1146 'templateconfig':1162 'text/html':920 'textarea':633,1464 'thread':834 'time':330,811 'toggl':1254 'token':1022 'topic-advanced-alchemy' 'topic-agent-skills' 'topic-agentskills' 'topic-ai-agents' 'topic-claude-code-plugin' 'topic-claude-code-skills' 'topic-gemini-cli-extension' 'topic-htmx' 'topic-inertia' 'topic-litestar' 'topic-mcp' 'topic-python' 'track':1057 'transpar':1023 'true':937 'truth':1206 'tsx':188,445,598,681,870,1399 'type':83,266,272,453,572,644,892,897,910,1215,1222,1408,1522 'typegen':278,457,1538,1570 'typegenconfig':512,573 'typescript':265,909,1211,1650 'union':252 'unless':1012 'upgrad':1607 'url':1107 'use':24,108,332,342,987,1048,1224 'useform':18,285,289,593,600,613,947,1019,1225,1247,1402,1433,1501 'usepag':19,448,465,831,1403,1419,1502 'user':223,377,408,421,437,1038,1307,1325,1343 'utf':532 'v1':1609 'v2':1495,1602,1610 'valid':238,596,918,1165,1357,1520 'validationexcept':655,1297,1367 'valu':624,634,785,795,818,1452,1465 'version':1053,1060,1062,1074 'via':273,284,830,1199,1217 'visit':926 'vite':33,65,77,133,166,213,276,508,534,583,901,1005,1071,1183,1258,1532,1628,1636,1661 'vite-serv':132 'vite.config.ts':222 'viteconfig':513,537,753 'viteconfig.inertia':126,772,1175 'vitejs.dev':66 'viteplugin':79,482,514,535,751,770,1180,1535 'vue':189,871,1087 'welcom':470 'well':1164 'wire':26,338,481,591,744,1593 'without':833 'workflow':741 'workspac':473 'x':935,943 'x-inertia':934,942","prices":[{"id":"2a42b926-9a82-4e3e-9015-96530bde823b","listingId":"44fc38ae-9413-4cfd-8b6d-b19964017663","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"litestar-org","category":"litestar-skills","install_from":"skills.sh"},"createdAt":"2026-05-18T13:20:57.721Z"}],"sources":[{"listingId":"44fc38ae-9413-4cfd-8b6d-b19964017663","source":"github","sourceId":"litestar-org/litestar-skills/litestar-inertia","sourceUrl":"https://github.com/litestar-org/litestar-skills/tree/main/skills/litestar-inertia","isPrimary":false,"firstSeenAt":"2026-05-18T13:20:57.721Z","lastSeenAt":"2026-05-18T19:13:54.137Z"}],"details":{"listingId":"44fc38ae-9413-4cfd-8b6d-b19964017663","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"litestar-org","slug":"litestar-inertia","github":{"repo":"litestar-org/litestar-skills","stars":7,"topics":["advanced-alchemy","agent-skills","agentskills","ai-agents","claude-code-plugin","claude-code-skills","gemini-cli-extension","htmx","inertia","litestar","mcp","python","sqlspec"],"license":"mit","html_url":"https://github.com/litestar-org/litestar-skills","pushed_at":"2026-05-13T16:04:09Z","description":"Opinionated first-party agent skills, plugins, subagents, slash commands, and MCP servers for the Litestar framework ecosystem — publishable to Claude Code, Gemini CLI, Codex CLI, Cursor, OpenCode, and VS Code/Copilot from a single repo.","skill_md_sha":"775b354cbe6533833fe2595894ab0cbd81211030","skill_md_path":"skills/litestar-inertia/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/litestar-org/litestar-skills/tree/main/skills/litestar-inertia"},"layout":"multi","source":"github","category":"litestar-skills","frontmatter":{"name":"litestar-inertia","description":"Auto-activate for litestar_vite.inertia, InertiaConfig, component= route handlers, @inertia, @inertiajs/react, @inertiajs/vue3, @inertiajs/svelte, createInertiaApp, useForm, usePage, Link, router, or resources/js/pages. Use when wiring Inertia.js with Litestar and litestar-vite for React, Vue, or Svelte server-driven SPAs. Not for JSON-API-only SPAs, HTMX apps, or non-Litestar backends."},"skills_sh_url":"https://skills.sh/litestar-org/litestar-skills/litestar-inertia"},"updatedAt":"2026-05-18T19:13:54.137Z"}}