Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

sillo-inertia

sillo-inertia is a modern Inertia.js adapter for Sillo with support for React and Vue. It renders normal HTML on first-page visits and Inertia page JSON for requests with X-Inertia: true.

Use the canonical import:

from sillo_inertia import Inertia, vite_react, vite_vue

Install

pip install sillo-inertia

Quick Start

React + Vite

from sillo import silloApp
from sillo.core.http import Request, Response
from sillo_inertia import Inertia, vite_react

app = silloApp()
inertia = Inertia(
    app,
    root_view="resources/views/app.html",
    version="1",
    vite=vite_react(dev=True),
)

@app.get("/")
async def home(request: Request, response: Response):
    return await inertia.render(request, response, "Home", {"name": "Sillo"})

Vue + Vite

from sillo import silloApp
from sillo.core.http import Request, Response
from sillo_inertia import Inertia, vite_vue

app = silloApp()
inertia = Inertia(
    app,
    root_view="resources/views/app.html",
    version="1",
    vite=vite_vue(dev=True),
)

@app.get("/")
async def home(request: Request, response: Response):
    return await inertia.render(request, response, "Home", {"name": "Sillo"})

Root View Template

Your resources/views/app.html must include the {{ inertia }} placeholder:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    {{ inertia_head }}
  </head>
  <body>
    <div id="{{ root_id }}"></div>
    {{ inertia }}
  </body>
</html>

{{ inertia }} expands to a <script type="application/json" data-page="app"> element holding the page object — that is where Inertia 2.x and later read it from. Do not put it on the root <div> as data-page: that was the 1.x convention, current clients never look there, and the page boots with a null page object and throws Cannot read properties of null (reading 'component'). If you are targeting a 1.x client, {{ inertia_page }} still gives you the HTML-escaped attribute value.

Features

  • Framework Agnostic: Full support for React and Vue (more to come)
  • Full-page HTML: Renders HTML on first-page visits
  • Inertia JSON: Responds with JSON for X-Inertia requests
  • Version Handling: Asset version conflict detection with HTTP 409 and X-Inertia-Location
  • Partial Reload: Supports X-Inertia-Partial-Component and X-Inertia-Partial-Data for efficient updates
  • Shared Props: Global props accessible to all pages
  • Sync & Async Props: Both sync callables and async functions work seamlessly
  • Lazy Props: Defer expensive computations with lazy() helper
  • Custom Root ID: Use any element ID for the Inertia mount point
  • Dynamic Versioning: Support for callable version functions

Configuration

Inertia Configuration

Inertia(
    app=app,                          # Sillo app instance (optional)
    root_view="app.html",             # Path to root template
    version="1.0.0",                  # Static or callable version
    root_id="app",                    # Root element ID
    base_dir=".",                     # Base directory for asset paths
    vite=vite_react(dev=True),        # Vite configuration
)

React Options

vite_react(
    entry="src/main.jsx",             # Entry point
    dev_server="http://localhost:5173", # Dev server URL
    manifest_path="dist/.vite/manifest.json",  # Production manifest
    asset_prefix="/assets/",          # Asset URL prefix
    dev=True,                         # Development mode
    react_refresh=True,               # Enable React Fast Refresh
)

Vue Options

vite_vue(
    entry="src/main.ts",              # Entry point
    dev_server="http://localhost:5173", # Dev server URL
    manifest_path="dist/.vite/manifest.json",  # Production manifest
    asset_prefix="/assets/",          # Asset URL prefix
    dev=True,                         # Development mode
)

API Reference

Rendering Pages

# Basic rendering with props
await inertia.render(
    request,
    response,
    "Home",                           # Component name
    {"user": {"name": "John"}},       # Props dict
    status_code=200,                  # HTTP status
    view_data={"title": "Home"},      # Extra template data
)

# Lazy props for expensive computations
from sillo_inertia import lazy

await inertia.render(
    request,
    response,
    "Home",
    {
        "user": {"id": 1, "name": "John"},
        "permissions": lazy(lambda r: compute_permissions(r)),
    }
)

Shared Props

inertia.share(
    app_name="MyApp",
    auth={"user": None},
)

Redirects

# Returns 303 for POST/PUT/PATCH, 302 for GET
inertia.redirect(request, response, "/dashboard")

# Custom status code
inertia.redirect(request, response, "/home", status_code=301)

Dynamic Props

Props can be static values, callables, or async functions:

# Static value
{"count": 5}

# Sync callable
{"count": lambda request: request.app.cache.get("count")}

# Async callable
async def get_count(request):
    return await request.app.db.count()

{"count": get_count}

# Lazy prop (deferred resolution)
{"data": lazy(lambda r: expensive_computation())}

Examples

User Dashboard

@app.get("/dashboard")
async def dashboard(request: Request, response: Response):
    user = await request.app.db.get_user(request.user_id)
    posts = lazy(lambda _: request.app.db.list_posts(request.user_id))
    
    return await inertia.render(
        request,
        response,
        "Dashboard",
        {
            "user": user.to_dict(),
            "posts": posts,
        }
    )

Form Submission

@app.post("/users")
async def create_user(request: Request, response: Response):
    data = await request.json()
    user = await request.app.db.create_user(data)
    return inertia.redirect(request, response, f"/users/{user.id}")

Partial Page Updates

# Client sends:
# GET /api/comments?post_id=1
# X-Inertia: true
# X-Inertia-Partial-Component: PostDetail
# X-Inertia-Partial-Data: comments

@app.get("/posts/{post_id}")
async def post_detail(request: Request, response: Response):
    post = await request.app.db.get_post(request.path_params["post_id"])
    comments = lazy(lambda _: request.app.db.list_comments(post.id))
    
    return await inertia.render(
        request,
        response,
        "PostDetail",
        {
            "post": post.to_dict(),
            "comments": comments,
        }
    )

Project Links

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sillo_inertia-0.0.1a2.tar.gz (44.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sillo_inertia-0.0.1a2-py3-none-any.whl (8.6 kB view details)

Uploaded Python 3

File details

Details for the file sillo_inertia-0.0.1a2.tar.gz.

File metadata

  • Download URL: sillo_inertia-0.0.1a2.tar.gz
  • Upload date:
  • Size: 44.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for sillo_inertia-0.0.1a2.tar.gz
Algorithm Hash digest
SHA256 17bf6e7b77f0a585c4f8fd768b85de27c3f3edc7fa35f63c7436461d7a3684bf
MD5 a2dac0bb2ecb66ddbb63590fa636e93c
BLAKE2b-256 5098ed29cf706b530e9ef3a857954b9b4281848c1f8ded1385364abb7b902a5d

See more details on using hashes here.

File details

Details for the file sillo_inertia-0.0.1a2-py3-none-any.whl.

File metadata

  • Download URL: sillo_inertia-0.0.1a2-py3-none-any.whl
  • Upload date:
  • Size: 8.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.1 {"installer":{"name":"uv","version":"0.12.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for sillo_inertia-0.0.1a2-py3-none-any.whl
Algorithm Hash digest
SHA256 9424b1383c78c8b2cfd51c675dd5b363f65f6ea088a10364d83acf55dbbaec5d
MD5 7f9c4e49267748a82f4922d13949e9fb
BLAKE2b-256 9bd518efc14981e2f6c7ebec068b8772cfa649f14aebf06ed4c1141d0bf316f5

See more details on using hashes here.

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