Skip to main content

forge-inertia

Inertia.js adapter for forge-kits / FastAPI.
Brings the Laravel Inertia workflow to Python — same protocol, same mental model.

pip install forge-kits-inertia

Requirements

  • Python ≥ 3.11
  • forge-kits ≥ 1.5.9
  • A Vite + Vue 3 (or React/Svelte) frontend with @inertiajs/vue3 (or equivalent)

Setup

1. Register the provider

# config/project.py
from forge_inertia import InertiaProvider

config = {
    "providers": [InertiaProvider],
    ...
}

2. Create config/inertia.py

# config/inertia.py
from forgeapi import env

config = {
    "dev_mode":     env("INERTIA_DEV", False),
    "vite_dev_url": env("VITE_DEV_URL", "http://localhost:5173"),
    # Optional overrides (shown with defaults):
    # "root_view":  "public/build/index.html",
    # "public_dir": "public",
    # "vite_entry": "src/main.ts",
    # "version":    "",   # auto-detected from Vite manifest when empty
}

3. Frontend entry (src/main.ts)

import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'
import './style.css'

createInertiaApp({
  resolve: name => {
    const pages = import.meta.glob('./Pages/**/*.vue', { eager: true })
    return pages[`./Pages/${name}.vue`]
  },
  setup({ el, App, props, plugin }) {
    createApp({ render: () => h(App, props) })
      .use(plugin)
      .mount(el)
  },
})

4. Vite config (vite.config.ts)

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  build: {
    outDir: '../public/build',
    emptyOutDir: true,
  },
})

Returning an Inertia response

from fastapi import Request
from fastapi.responses import Response
from forgeapi.controllers import Controller, route
from forge_inertia import Inertia

class DashboardController(Controller):
    prefix = "/dashboard"

    @route.get("/", response_class=Response)
    async def index(self, request: Request) -> Response:
        return Inertia("Dashboard", props={"stats": await get_stats()}, request=request)

The component name maps directly to Pages/Dashboard.vue (or .tsx, .svelte).

Lazy (callable) props

Props that are callables are only evaluated when actually needed — useful for partial reloads:

return Inertia("Dashboard", props={
    "user":  current_user.dict(),       # always evaluated
    "stats": lambda: get_heavy_stats(), # skipped on partial reloads that don't request it
}, request=request)

Shared data

Equivalent of Laravel's HandleInertiaRequests middleware — data shared on every response.

# config/project.py (or a dedicated boot file)
from forge_inertia import inertia_share

# Static value
inertia_share("app_name", "My App")

# Per-request callable — receives FastAPI Request
inertia_share("auth", lambda req: {
    "user": req.state.user.dict() if hasattr(req.state, "user") else None,
})

Shared props are merged with page props on every Inertia response. Page props override shared props on key collision.


Partial reloads

forge-inertia handles X-Inertia-Partial-Data / X-Inertia-Partial-Component automatically:

  • Props not in the requested set are excluded from the response.
  • Shared prop callables not in the set are never called.
  • Page prop callables (lambdas) not in the set are never called.
  • If the component name doesn't match, all props are returned normally.

No controller changes required — the adapter filters at the response layer.


Configuration reference

All options with their defaults:

Key Default Description
root_view "public/build/index.html" Compiled HTML shell served on initial load
public_dir "public" Static assets root (mounted at /build)
version "" Asset version; auto-set from Vite manifest when empty
dev_mode False True → serve from Vite dev server (full HMR, no build step)
vite_dev_url "http://localhost:5173" Vite dev server base URL
vite_entry "src/main.ts" Frontend entry point (injected in dev HTML shell)

Dev workflow

Two terminals:

# Frontend (in resources/)
npm run dev

# Backend (in project root)
forgeapi runserver --reload

Set INERTIA_DEV=true in .env. The backend serves an HTML shell that loads JS/CSS directly from the Vite dev server — full HMR, no build step.

Production

# Build frontend
npm run build   # outputs to public/build/

# Run server
forgeapi runserver

InertiaProvider auto-mounts /build as static files and reads the Vite manifest to set the asset version hash (SHA-1, deterministic across restarts).


Protocol compatibility

Feature Status
Initial page load (HTML shell) ✅
Subsequent navigation (XHR/JSON) ✅
Asset version mismatch → 409 + hard reload ✅
POST/PUT/PATCH/DELETE 302 → 303 redirect ✅
Shared props (per-request callables) ✅
Partial reloads (X-Inertia-Partial-Data) ✅
Lazy (callable) page props ✅
SSR ❌ not yet

Metadata

Release files for forge-kits-inertia 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for forge-kits-inertia 0.1.0
File Size Uploaded
forge_kits_inertia-0.1.0.tar.gz 7.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for forge-kits-inertia 0.1.0
File Interpreter ABI Platform
forge_kits_inertia-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 15.1 kB

Release files / forge_kits_inertia-0.1.0.tar.gz

Download URL forge_kits_inertia-0.1.0.tar.gz
Size 7.9 kB
Tags Source
SHA-256 checksum
How to use checksums
fb91da25a3d2dfcf429bc54789c01ebaf458622df94ca479353c94747b9c6ada
BLAKE2b-256 checksum
How to use checksums
e94f696d537bcb30a18134e06bb8f8255210b0dcea84233573f9861daabf38b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / forge_kits_inertia-0.1.0-py3-none-any.whl

Download URL forge_kits_inertia-0.1.0-py3-none-any.whl
Size 7.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9f8605d2ce85523739254dc4348c515a01e5e13be43c47a1aebecb556bc17051
BLAKE2b-256 checksum
How to use checksums
c461814dcf912622c2c6f5cd01aa953b0b6cb8c056408e46826b5c91b166b0dc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

0.1.2

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page