Vite
The ViteProvider integrates Vite asset bundling with your application. It supports both HMR development mode and manifest-based production mode, and injects vite(), vite_asset(), and vite_react_refresh() helpers into Jinja2 templates.
Setup
The Vite integration is included in the core fastapi-startkit package, so no further installation is required. Register ViteProvider in your application:
# bootstrap/application.py
from fastapi_startkit.vite import ViteProvider
app = Application(
base_path=...,
providers=[
ViteProvider,
...
],
)Publish the default config and asset files:
python artisan provider:publish --provider=viteThis creates the following files in your project:
config/vite.py: FastAPI configuration for Vite.package.json: Vite dependencies and scripts.vite.config.js: Vite configuration with Tailwind CSS support.resources/js/app.ts: Main entry point.resources/css/app.css: Main CSS entry point.templates/index.html: Example template using Vite.
After publishing, install the frontend dependencies and start the development server:
npm install
npm run devNOTE
Ensure APP_URL in your .env matches your FastAPI server URL (e.g., http://127.0.0.1:8000) so that Vite's Hot Module Replacement (HMR) can correctly communicate with the backend.
Configuration
config/vite.py uses a ViteConfig dataclass with these defaults:
from fastapi_startkit.vite import ViteConfig
config = ViteConfig(
public_path="public", # Root directory for assets
build_directory="build", # Subfolder inside public_path for production build
hot_file="hot", # Presence of this file signals dev server is running
manifest_filename="manifest.json",
asset_url="", # Optional CDN prefix for asset URLs
static_url="/build", # URL prefix used when mounting static files
mount_static=True, # Auto-mount public/build as a StaticFiles route
)To use your custom configuration, pass the ViteConfig class when registering the provider. This is optional; if omitted, the provider will use the default settings.
from config.vite import ViteConfig
app = Application(
providers=[
(ViteProvider, ViteConfig),
],
)Development Mode (HMR)
Start the Vite dev server:
npm run devWhen the public/hot file exists, the Vite class switches to HMR mode automatically. Asset tags point to the HMR server (default: http://localhost:5173) instead of the build directory.
The hot file's content is the HMR origin URL. Vite writes it automatically; you can also create it manually:
http://localhost:5173Production Mode
Build your assets:
npm run buildVite writes public/build/manifest.json. The framework reads this manifest at startup (cached in memory) and generates hashed asset URLs with preload tags.
Template Helpers
With Jinja2 templates registered (via ViteProvider), three globals are available:
vite(entrypoint)
Generates <script type="module"> and <link rel="stylesheet"> tags plus <link rel="modulepreload"> preloads for the given entry point:
{# templates/index.html #}
{{ vite('resources/js/app.tsx') }}Multiple entry points:
{{ vite(['resources/js/app.tsx', 'resources/css/admin.css']) }}vite_asset(path)
Returns the public URL for a non-entry-point asset (images, fonts, etc.):
<img src="{{ vite_asset('resources/images/logo.png') }}">vite_react_refresh()
Injects the React Fast Refresh preamble. Required for React HMR. Must appear before vite():
{{ vite_react_refresh() }}
{{ vite('resources/js/app.tsx') }}In production mode, vite_react_refresh() returns an empty string — safe to always include.
CSP Nonce
vite = app.make("vite")
nonce = vite.use_csp_nonce() # generates a random nonce
# pass nonce to template context, set it in your CSP headerAll generated script and link tags will include the nonce attribute.
Custom Asset URL Resolver
Override how asset URLs are built (e.g., to add a CDN prefix dynamically):
vite = app.make("vite")
vite.create_asset_paths_using(lambda path: f"https://cdn.example.com/{path}")SRI Integrity
The manifest chunk key "integrity" is read by default and included as the integrity attribute on generated tags. Change the key or disable it:
vite.use_integrity_key("sri") # use a different key
vite.use_integrity_key(False) # disable integrity attributes