Plugin¶
Vite Plugin for Litestar.
This module provides the VitePlugin class for integrating Vite with Litestar. The plugin handles:
Static file serving configuration
Jinja2 template callable registration
Vite dev server process management
Async asset loader initialization
Development proxies for Vite HTTP and HMR WebSockets (with hop-by-hop header filtering)
Example:
from litestar import Litestar
from litestar_vite import VitePlugin, ViteConfig
app = Litestar(
plugins=[VitePlugin(config=ViteConfig(dev_mode=True))],
)
- class litestar_vite.plugin.ProxyHeadersMiddleware[source]¶
Bases:
AbstractMiddlewareASGI middleware for secure proxy header handling.
Only processes X-Forwarded-* headers when the direct caller (scope[“client”]) is in the trusted hosts list. This prevents header spoofing attacks.
- Handles:
X-Forwarded-Proto: Sets scope[“scheme”] (http/https/ws/wss)
X-Forwarded-For: Sets scope[“client”] to the real client IP
X-Forwarded-Host: Optionally sets the Host header
- Security:
Never blindly trusts headers from any client. Validates caller IP against trusted hosts before reading headers. Validates scheme values to only allow http/https/ws/wss.
Example:
from litestar_vite import VitePlugin, ViteConfig from litestar_vite.config import RuntimeConfig # Trust all proxies (Railway, Heroku, container environments) app = Litestar( plugins=[VitePlugin(config=ViteConfig( runtime=RuntimeConfig(trusted_proxies="*") ))] ) # Trust specific proxy IPs app = Litestar( plugins=[VitePlugin(config=ViteConfig( runtime=RuntimeConfig(trusted_proxies=["10.0.0.0/8", "172.16.0.0/12"]) ))] )
- class litestar_vite.plugin.StaticFilesConfig[source]¶
Bases:
objectConfiguration for static file serving.
This configuration is passed to Litestar’s static files router.
- __init__(after_request: AfterRequestHookHandler | None = None, after_response: AfterResponseHookHandler | None = None, before_request: BeforeRequestHookHandler | None = None, cache_control: CacheControlHeader | None = None, exception_handlers: ExceptionHandlersMap | None = None, guards: list[Guard] | None = None, middleware: Sequence[Middleware] | None = None, opt: dict[str, Any] | None = None, security: Sequence[SecurityRequirement] | None = None, tags: Sequence[str] | None = None) None¶
- class litestar_vite.plugin.TrustedHosts[source]¶
Bases:
objectContainer for trusted proxy hosts and networks.
Provides efficient lookup for IP addresses and CIDR networks. Following Uvicorn’s security model for proxy header validation.
- Supports:
Wildcard “*” to trust all hosts (for controlled environments)
IPv4 addresses: “192.168.1.1”
IPv6 addresses: “::1”
CIDR notation: “10.0.0.0/8”, “fd00::/8”
Literals for non-IP hosts (e.g., Unix socket paths)
- __contains__(host: str | None) bool[source]¶
Check if a host is trusted.
- Parameters:
host¶ – The host to check. Can be an IP address or literal.
- Returns:
True if the host is trusted, False otherwise.
- __init__(trusted_hosts: list[str] | str) None[source]¶
Initialize trusted hosts container.
- Parameters:
trusted_hosts¶ – A single host, comma-separated string, or list of hosts. Use “*” to trust all hosts (only in controlled environments).
- get_trusted_client_host(x_forwarded_for: str) str[source]¶
Extract the real client IP from X-Forwarded-For header.
The X-Forwarded-For header contains a comma-separated list of IPs. Each proxy appends the client IP to the list. We find the first untrusted host (reading from right to left) which is the real client.
- Parameters:
x_forwarded_for¶ – The X-Forwarded-For header value.
- Returns:
The first untrusted host in the chain, or the original client if all hosts are trusted.
- class litestar_vite.plugin.VitePlugin[source]¶
Bases:
InitPluginProtocol,CLIPluginVite plugin for Litestar.
This plugin integrates Vite with Litestar, providing:
Static file serving configuration
Jinja2 template callables for asset tags
Vite dev server process management
Async asset loader initialization
Example:
from litestar import Litestar from litestar_vite import VitePlugin, ViteConfig app = Litestar( plugins=[ VitePlugin(config=ViteConfig(dev_mode=True)) ], )
- __init__(config: ViteConfig | None = None, asset_loader: ViteAssetLoader | None = None, static_files_config: StaticFilesConfig | None = None) None[source]¶
Initialize the Vite plugin.
- property config: ViteConfig¶
Get the Vite configuration.
- Returns:
The ViteConfig instance.
- property asset_loader: ViteAssetLoader¶
Get the asset loader instance.
Lazily initializes the loader if not already set.
- Returns:
The ViteAssetLoader instance.
- property spa_handler: AppHandler | None¶
Return the configured SPA handler when SPA mode is enabled.
- Returns:
The AppHandler instance, or None when SPA mode is disabled/not configured.
- property proxy_client: AsyncClient | None¶
Return the shared httpx.AsyncClient for proxy requests.
The client is initialized during app lifespan (dev mode only) and provides connection pooling, TLS session reuse, and HTTP/2 multiplexing benefits.
- Returns:
The shared AsyncClient instance, or None if not initialized or not in dev mode.
- on_cli_init(cli: Group) None[source]¶
Register CLI commands.
- Parameters:
cli¶ – The Click command group to add commands to.
- on_app_init(app_config: AppConfig) AppConfig[source]¶
Configure the Litestar application for Vite.
This method wires up supporting configuration for dev/prod operation:
Adds types used by generated handlers to the signature namespace.
Ensures a consistent NotFound handler for asset/proxy lookups.
Registers optional Inertia and Jinja integrations.
Configures static file routing when enabled.
Configures dev proxy middleware based on proxy_mode.
Creates/initializes the SPA handler where applicable and registers lifespans.
- Parameters:
app_config¶ – The Litestar application configuration.
- Returns:
The modified application configuration.
- server_lifespan(app: Litestar) Iterator[None][source]¶
Server-level lifespan context manager (runs ONCE per server, before workers).
This is called by Litestar CLI before workers start. It handles: - Environment variable setup (with logging) - Vite dev server process start/stop (ONE instance for all workers) - Type export on startup
Note: SPA handler and asset loader initialization happens in the per-worker lifespan method, which is auto-registered in on_app_init.
Hotfile behavior: the hotfile is written before starting the dev server to ensure proxy middleware and SPA handlers can resolve a target URL immediately on first request.
- Parameters:
app¶ – The Litestar application instance.
- Yields:
None
- lifespan(app: Litestar) AsyncIterator[None][source]¶
Worker-level lifespan context manager (runs per worker process).
This is auto-registered in on_app_init and handles per-worker initialization: - Environment variable setup (silently - each worker needs process-local env vars) - Shared proxy client initialization (dev mode only, for ViteProxyMiddleware/SSRProxyController) - Asset loader initialization - SPA handler initialization - Route metadata injection
Note: The Vite dev server process is started in server_lifespan, which runs ONCE per server before workers start.
- Parameters:
app¶ – The Litestar application instance.
- Yields:
None
- class litestar_vite.plugin.ViteProcess[source]¶
Bases:
objectManages the Vite development server process.
This class handles starting and stopping the Vite dev server process, with proper thread safety and graceful shutdown. It registers signal handlers for SIGTERM and SIGINT to ensure child processes are terminated even if Python is killed externally.
- __init__(executor: JSExecutor) None[source]¶
Initialize the Vite process manager.
- Parameters:
executor¶ – The JavaScript executor to use for running Vite.
- start(command: list[str], cwd: Path | str | None) None[source]¶
Start the Vite process.
- Parameters:
If the process exits immediately, this method captures stdout/stderr and raises a ViteProcessError with diagnostic details.
- Raises:
ViteProcessError – If the process fails to start.
- stop(timeout: float = 5.0) None[source]¶
Stop the Vite process and all its child processes.
Uses process groups to ensure child processes (node, astro, nuxt, vite, etc.) are terminated along with the parent npm/npx process.
- Parameters:
timeout¶ – Seconds to wait for graceful shutdown before killing.
- Raises:
ViteProcessError – If the process fails to stop.
- class litestar_vite.plugin.ViteProxyMiddleware[source]¶
Bases:
AbstractMiddlewareASGI middleware to proxy Vite dev HTTP traffic to internal Vite server.
HTTP requests use httpx.AsyncClient with optional HTTP/2 support for better connection multiplexing. WebSocket traffic (used by Vite HMR) is handled by a dedicated WebSocket route handler created by create_vite_hmr_handler().
The middleware reads the Vite server URL from the hotfile dynamically, ensuring it always connects to the correct Vite server even if the port changes.
- __init__(app: ASGIApp, hotfile_path: Path, asset_url: str | None = None, resource_dir: Path | None = None, bundle_dir: Path | None = None, root_dir: Path | None = None, http2: bool = True, plugin: VitePlugin | None = None) None[source]¶
Initialize the middleware.
- Parameters:
app¶ – The
nextASGI app to call.exclude¶ – A pattern or list of patterns to match against a request’s path. If a match is found, the middleware will be skipped.
exclude_opt_key¶ – An identifier that is set in the route handler
optkey which allows skipping the middleware.scopes¶ – ASGI scope types, should be a set including either or both ‘ScopeType.HTTP’ and ‘ScopeType.WEBSOCKET’.
- litestar_vite.plugin.create_ssr_proxy_controller(target: str | None = None, hotfile_path: Path | None = None, http2: bool = True, plugin: VitePlugin | None = None) type[source]¶
Create a Controller that proxies to an SSR framework dev server.
This controller is used for SSR frameworks (Astro, Nuxt, SvelteKit) where all non-API requests should be proxied to the framework’s dev server for rendering.
- Parameters:
- Returns:
A Litestar Controller class with HTTP and WebSocket handlers for SSR proxy.
- litestar_vite.plugin.create_vite_hmr_handler(hotfile_path: Path, hmr_path: str = '/static/vite-hmr', asset_url: str = '/static/') Any[source]¶
Create a WebSocket route handler for Vite HMR proxy.
This handler proxies WebSocket connections from the browser to the Vite dev server for Hot Module Replacement (HMR) functionality.
- litestar_vite.plugin.get_litestar_route_prefixes(app: Litestar) tuple[str, ...][source]¶
Build a cached list of Litestar route prefixes for the given app.
This function collects all registered route paths from the Litestar application and caches them for efficient lookup. The cache is stored in app.state to ensure it’s automatically cleaned up when the app is garbage collected.
Includes: - All registered Litestar route paths - OpenAPI schema path (customizable via openapi_config.path) - Common API prefixes as fallback (/api, /schema, /docs)
- Parameters:
app¶ – The Litestar application instance.
- Returns:
A tuple of route prefix strings (without trailing slashes).
- litestar_vite.plugin.is_litestar_route(path: str, app: Litestar) bool[source]¶
Check if a path matches a registered Litestar route.
This function determines if a request path should be handled by Litestar rather than proxied to the Vite dev server or served as SPA content.
A path matches if it equals a registered prefix or starts with prefix + “/”.
- litestar_vite.plugin.resolve_litestar_version() str[source]¶
Return the installed Litestar version string.
- Returns:
The installed Litestar version, or “unknown” when unavailable.
- litestar_vite.plugin.set_app_environment(app: Litestar) None[source]¶
Set environment variables derived from the Litestar app instance.
This is called after set_environment() once the app is available, to export app-specific configuration like OpenAPI paths.
- Parameters:
app¶ – The Litestar application instance.