Static File Serving & Hot Loading¶
Overview¶
Vuer includes a built-in static file server that allows you to serve 3D models, textures, and other assets alongside your visualization. This guide covers how to configure static file serving and use hot loading for assets that change frequently during development.
Static File Configuration¶
The workspace Parameter¶
When initializing your Vuer application, you can specify where static files are served from using the workspace parameter:
from vuer import Vuer
# Serve static files from the current directory (default)
app = Vuer(workspace=".")
# Or specify a custom path
app = Vuer(workspace="/path/to/your/assets")
# Or use Path objects
from pathlib import Path
app = Vuer(workspace=Path(__file__).parent / "assets")
Note: The
static_rootparameter is deprecated. Useworkspaceinstead.
URL Structure¶
Static files are served under the /static endpoint. For example:
app = Vuer(workspace="./my_assets")
# File at: ./my_assets/models/robot.obj
# Accessible via: /static/models/robot.obj
Using Static Files in Your Scene¶
Once configured, you can reference static files in your Vuer components:
from vuer import Vuer, VuerSession
from vuer.schemas import DefaultScene, Obj, ImageBackground
app = Vuer(workspace="./assets")
@app.spawn(start=True)
async def main(session: VuerSession):
session.set @ DefaultScene(
# Load 3D model from static files
Obj(
key="robot",
src="/static/models/robot.obj",
mtl="/static/models/robot.mtl"
),
# Use texture as background
ImageBackground(
src="/static/textures/skybox.jpg"
)
)
await session.forever()
Hot Loading with ?hot¶
What is Hot Loading?¶
In Vuer, hot loading is a concept for handling assets that change frequently during development. When you mark an asset as “hot”, Vuer treats it as dynamic content that should always reflect the latest version from disk.
Think of hot loading as telling Vuer:
“This asset is actively being edited. Always show me the newest version.”
This is especially useful when:
Iteratively refining 3D models, textures, or materials
Experimenting with different asset variations
Debugging asset-related issues
Using Hot URLs¶
To mark an asset as hot, append ?hot to its URL:
# Development: Hot loading for frequently changing assets
session.upsert @ Obj(
key="model",
src="/static/model.obj?hot",
mtl="/static/model.mtl?hot"
)
# Or with textures
session.upsert @ ImageBackground(
src="/static/environment.jpg?hot"
)
Hot URL Syntax¶
The ?hot parameter can appear anywhere in the query string:
/static/model.obj?hot âś… Works
/static/model.obj?hot&debug=true âś… Works (any position)
/static/model.obj?v=1&hot âś… Works (any position)
To explicitly disable hot loading, set it to false:
/static/model.obj?hot=false ❌ Hot loading disabled
How Hot Loading Works¶
When an asset is marked as hot:
Loader behavior: Vuer tells the browser to always check for updates
Instant updates: When you save changes to the file, they appear immediately
Efficient: Unchanged files are not re-downloaded (uses HTTP 304 responses)
This creates a smooth development experience where your changes are reflected instantly without manual page refreshes or cache clearing.
Development vs Production¶
Development Mode (Hot Assets)¶
During development, mark assets you’re actively editing as hot:
@app.spawn(start=True)
async def main(session: VuerSession):
session.set @ DefaultScene(
# Hot loading for assets being actively edited
Obj(
key="robot",
src="/static/robot.obj?hot",
mtl="/static/robot.mtl?hot"
)
)
Production Mode (Static Assets)¶
In production, omit the ?hot parameter to allow efficient browser caching:
@app.spawn(start=True)
async def main(session: VuerSession):
session.set @ DefaultScene(
# Standard loading with browser caching
Obj(
key="robot",
src="/static/robot.obj",
mtl="/static/robot.mtl"
)
)
Pattern: Conditional Hot Loading¶
You can conditionally enable hot loading based on your environment:
from pathlib import Path
from vuer import Vuer, VuerSession
from vuer.schemas import DefaultScene, Obj, Pcd
app = Vuer(workspace=Path(__file__).parent / "assets")
@app.spawn(start=True)
async def main(session: VuerSession):
# Determine if in development mode
DEV_MODE = True # Toggle based on your environment
# Helper function to create hot URLs in dev mode
def asset(path: str) -> str:
"""Mark asset as hot in development mode."""
return f"{path}?hot" if DEV_MODE else path
session.set @ DefaultScene(
Obj(
key="robot",
src=asset("/static/models/robot.obj"),
mtl=asset("/static/models/robot.mtl")
),
Pcd(
key="scan",
src=asset("/static/scans/room.ply")
)
)
await session.forever()
Using Environment Variables¶
For more flexibility, use environment variables to control hot loading:
import os
from vuer import Vuer, VuerSession
from vuer.schemas import DefaultScene, Obj
app = Vuer(workspace="./assets")
# Check if running in production
IS_PRODUCTION = os.getenv("PRODUCTION", "false").lower() == "true"
def asset(path: str) -> str:
"""Generate asset URL with hot loading in development."""
return path if IS_PRODUCTION else f"{path}?hot"
@app.spawn(start=True)
async def main(session: VuerSession):
session.set @ DefaultScene(
Obj(
key="model",
src=asset("/static/model.obj"),
mtl=asset("/static/model.mtl")
)
)
await session.forever()
Then run with:
# Development (with hot loading)
python my_app.py
# Production (standard loading)
PRODUCTION=true python my_app.py
Understanding Hot vs Static Assets¶
Hot Assets (?hot)¶
Use for: Assets you’re actively editing
Behavior: Always reflect latest version from disk
Performance: Minimal overhead (uses HTTP 304 for unchanged files)
Example: Model you’re refining in Blender, texture you’re adjusting
Static Assets (no parameter)¶
Use for: Stable assets that rarely change
Behavior: Browser caches efficiently
Performance: Optimal (no server requests after initial load)
Example: Final models, published textures, shared assets
Best Practices¶
Development workflow:
Mark assets as
?hotwhile actively editing themRemove
?hotonce assets are finalized
Performance:
Don’t mark all assets as hot—only those you’re currently working on
Static assets load faster and reduce server load
Team collaboration:
Use environment variables to automatically enable hot loading in development
This prevents accidentally deploying hot URLs to production
Debugging:
If you don’t see changes, verify the asset has
?hotin the URLCheck the browser network tab to confirm the file is being fetched
Complete Example¶
Here’s a complete example showing hot loading for development:
from pathlib import Path
from vuer import Vuer, VuerSession
from vuer.schemas import DefaultScene, Obj, Pcd, ImageBackground
app = Vuer(
workspace=Path(__file__).parent / "assets",
port=8012
)
@app.spawn(start=True)
async def main(session: VuerSession):
session.set @ DefaultScene(
# Model you're actively refining - hot load
Obj(
key="robot",
src="/static/models/robot.obj?hot",
mtl="/static/models/robot.mtl?hot"
),
# Stable point cloud - standard load
Pcd(
key="background-scan",
src="/static/scans/room.ply"
),
# Texture you're tweaking - hot load
ImageBackground(
src="/static/backgrounds/sky.jpg?hot"
)
)
await session.forever()
Summary¶
workspace: Configure where static files are served from (replaces deprecatedstatic_root)?hot: Mark frequently changing assets for instant updatesHot loading: A development concept for assets that change often
Production: Remove
?hotfor optimal caching and performance
Hot loading provides a seamless development experience where your asset changes are instantly visible, without the complexity of build systems or manual cache management.
See Also¶
Session APIs - Managing scene updates
Loading 3D Models - Examples of loading different formats
Component Index - All available 3D model components