Migrating from 0.0.1
A prop-by-prop map from the 0.0.1 API to 1.0.0, and an honest account of why it is a clean break.
Why a clean break
1.0.0 is not a compatible upgrade. DashModelViewer is gone; there is no shim that keeps old code running.
That is a deliberate decision rather than an oversight, and the argument for the other choice was real: the package had roughly 253 downloads a month, and a deprecating wrapper would have cost little. What tipped it was that the parts most in need of changing — hotspots, AR defaults, and the complete absence of output props — could not be fixed while preserving the old surface. A compatibility layer would have frozen the exact shapes that made the component hard to use.
So: rename, and say so loudly.
Side by side
# 0.0.1
from dash_model_viewer import DashModelViewer
DashModelViewer(
id="viewer",
src="/assets/shoe.glb",
alt="A shoe",
cameraControls=True,
arModes="webxr scene-viewer quick-look", # you had to know to set this
arButtonText="View in your space",
hotspots=[
{"slot": "hotspot-1", "position": "0 1 0", "text": "Sole",
"children_classname": "label"},
],
)
# 1.0.0
import dash_model_viewer as dmv
from dash import html
dmv.ModelViewer(
id="viewer",
src="/assets/shoe.glb",
alt="A shoe",
camera_controls=True,
# ar_modes now defaults to "webxr scene-viewer quick-look"
children=[
dmv.Slot(slot="hotspot-1", position="0 1 0",
class_name="label", children="Sole"),
dmv.Slot(slot="ar-button",
children=html.Button("View in your space")),
],
)
Prop map
| 0.0.1 | 1.0.0 | Notes |
|---|---|---|
DashModelViewer | ModelViewer | Import name unchanged; class renamed. |
cameraControls | camera_controls | All props are snake_case now. |
touchAction | touch_action | |
cameraOrbit / cameraTarget | camera_orbit / camera_target | Now also readable via camera. |
fieldOfView, minFieldOfView, maxFieldOfView | field_of_view, … | |
minCameraOrbit / maxCameraOrbit | min_camera_orbit / max_camera_orbit | |
interpolationDecay | interpolation_decay | |
toneMapping | tone_mapping | |
shadowIntensity | shadow_intensity | |
arModes | ar_modes | Default fixed — see below. |
arScale | ar_scale | |
variantName | variant_name | |
hotspots=[{...}] | children=[Slot(...)] | Now takes any Dash component. |
arButtonText="…" | Slot(slot="ar-button", children=…) | |
customArPrompt=… | Slot(slot="ar-prompt", children=…) | |
customArFailure=… | Slot(slot="ar-failure", children=…) | |
loading_state | (none) | Not this package's removal — Dash 4 dropped loading_state from components generally. Use dcc.Loading, or model_state for this component's own progress. |
id, src, alt (declared required) | src, alt enforced | 0.0.1's generated metadata declared all three required; nothing in 1.0.0 checked until now. src and alt now raise at construction if missing. id stays optional — a viewer with no callbacks needs none. |
| (none) | camera, model_state, model_info, ar_status, ar_tracking, scene_point | The half that never worked. camera is {"orbit", "target", "field_of_view"} — see below. |
| (none) | attributes, mv_* | Full upstream parity. |
| (none) | camera_change_debounce | Mandatory guard. |
| (none) | pick_on_click | Arms scene_point. |
Hotspot dictionaries → Slot
| Old key | New |
|---|---|
slot | Slot(slot=...) |
position | Slot(position=...) |
normal | Slot(normal=...) |
text | Slot(children="...") — or any component |
children_classname | Slot(class_name=...) |
orbit / target / fov | A callback on Slot.n_clicks writing the camera props |
The last row is the significant one. Camera-preset hotspots used to be declared inside the hotspot dict and handled invisibly by the component's JavaScript. They are now an ordinary callback, which means you can log them, animate them, gate them on auth, or compute them — see Camera and views.
Delete your clientside callbacks
If you copied the 0.0.1 examples you will have an assets/model_viewer_clientside.js and a clientside_callback for anything the component could not report. All of it is replaceable:
| You were doing this in JS | Now |
|---|---|
Reading getCameraOrbit() into a dcc.Store | Input("viewer", "camera") |
getDimensions() for a bounding box | Input("viewer", "model_info") |
availableVariants for a dropdown | model_info["variants"] |
Listening for load / progress | Input("viewer", "model_state") |
Listening for ar-status / ar-tracking | ar_status / ar_tracking |
positionAndNormalFromPoint() on click | pick_on_click=True → scene_point |
| Wiring hotspot clicks | Slot.n_clicks |
The AR default
Worth calling out separately because it changes behaviour silently rather than loudly. 0.0.1 shipped:
arModes = "basic_annotations scene-viewer quick-look"
basic_annotations is not an AR mode — it was a folder name in usage_tests/. webxr was therefore absent, and in-page WebXR AR never ran in a default configuration. If your code explicitly set arModes, you were unaffected; if it did not, you were running without WebXR and had no way to know.
You can now delete any explicit ar_modes="webxr scene-viewer quick-look" — that is the default. See Augmented reality.
Things that no longer exist
camera["source"]— removed in 1.0.0 before release. The shim reports
camera movement only for user interaction (that is the echo suppression which stops a callback writing camera_orbit from re-triggering itself), so source could only ever hold the single string "user-interaction". A key with one possible value tells a reader nothing, and reading it invited the belief that some other value was reachable. The payload is now {"orbit", "target", "field_of_view"}. The suppression itself is unchanged.
dash_model_viewer.DashModelViewer— renamed.- The generated R and Julia bindings — removed; they were generated and unused.
package-info.jsoninside the package —__version__now comes from
installed metadata.
- The runtime CDN fetch of
model-viewer3.5.0 — the bundle ships in the wheel
at 4.3.1. If you relied on the CDN behaviour, dmv.configure(use_cdn=True) restores it.
Source: /migrating
Note for AI agents: This is the static, prerendered view of an interactive Dash application served because we detected a non-JS user agent. Full prose docs:
- /migrating/llms.txt — LLM-friendly documentation
- /sitemap.xml
- /robots.txt