Added
- #4099 Streaming callbacks over HTTP now require shared storage and fail at server setup without it, instead of falling back to one connection per stream; WebSocket streaming callbacks do not need it.
- #4095 Make shared storage and the multiplexed streaming downlink opt-in (
shared_storage=orDASH_SHARED_STORAGE), and movemsgspecto a newdash[shared_storage]extra for the persistentLocalSharedStoragemodes (dash[diskcache]anddash[redis]include it). - #4026 Add
DASH_SECRET_KEYso a hosting platform can give every worker and pod the same signing secret for page, background and stream tokens without editing the app (server.secret_keystill wins and is not changed). - #4026 Add
DASH_SHARED_STORAGEto pick the shared-storage backend when the app does not passshared_storage=:local,none,diskcache:///abs/path, or aredis:///rediss://URL. - #4024 Add support for social media meta tags in regular Dash apps using
app.title,app.description, andapp.image. - #3976 Add a new
scrollToTopprop todcc.Linkto control whether the page scrolls to the top after client-side navigation. It defaults toTrueto preserve the existing behavior. Fixes #3974. - #3947 Make
plotly-clouda default install dependency of Dash instead of an optional extra, so theplotlyCLI and Dash's cloud integration work out of the box. Thedash[cloud]extra is kept for backward compatibility. - #3930 Add shared storage: a backend-agnostic cross-process state manager (key/value with optional TTL, plus ordered replayable pub/sub) via
dash.ctx.shared_storage, started lazily. ShipsLocalSharedStorage(in-memory with optional disk persistence),DiskcacheSharedStorage, andRedisSharedStoragefor horizontally-scaled deployments; see.ai/ARCHITECTURE.md. - #3931 Add streaming callbacks: an
async defgenerator callback streams its yields to the browser as they are produced (dash.Patchyields apply incrementally). A browser's streams share one SharedWorker-hosted connection so they do not count against the per-host connection limit; closing a tab cancels its streams. - #3977 Add partial WebSocket prop reads with
get_prop(..., path=...). Closes #3975. - #3765 Add opt-in partial pattern matching for callback
Input,Output, andStateviapartial_pattern=True, so dictionary ID patterns can match component IDs with extra keys and combine withALL/MATCHwildcards. Fixes #3764. - #3880 Add experimental support for React 19 (default stays React 18.3.1); opt in with
REACT_VERSION=19.2.4ordash._dash_renderer._set_react_version("19.2.4"). Dash serves theumd-reactpackage with a compatibility shim so component libraries built against React <=18 keep working; see.ai/ARCHITECTURE.md. - #3925 Add optional callback request payload compression via
compress_payloadandcompress_thresholdcallback parameters (default threshold 5,000 bytes), sending gzip payloads that Dash decompresses on Flask, FastAPI, and Quart. Fixes #3924. - #3961 Added cursor position data (
xPixel,yPixel) todcc.GraphhoverDataandclickDatawhenhoveranywhereorclickanywhereis enabled in the figure. - #3960 Rewrite
dcc.Markdownanddcc.Linkas Typescript components - #3881 Added
dash.remount, a wrapper for a callback-returned component that forces the renderer to remount it (resetting its internal state) instead of reconciling in place: the explicit way to reset a stateful component from a callback without changing itsid.
Removed
- #3880 Remove React 16 support (
16.14.0is no longer an accepted value forREACT_VERSION/_set_react_version). - #4039 Remove unnecessary Python version checks (pre 3.9).
Changed
- #4073 Move
plotly-cloudback to the optionaldash[cloud]extra (it was a default dependency in 4.5.0rc0/rc1), since it is not available on conda-forge. - #4026 Log a warning, once per process, when a streaming request is refused because its stream token failed verification, which on multi-worker deployments usually means the workers do not share a signing secret.
- #3987 Forward FastAPI reload scope options (
reload_dirs,reload_excludes, andreload_includes) to Uvicorn when reloading. - #3986 Adjust
_run_before_hooksin thefastapibackend to honor a response returned by abefore_requestfunction, matching theflaskbackend's behavior.
Fixed
- #4075
fastapibackend: runbefore_requesthooks on every route of the Dash app (assets, hook routes,api_endpoint, pages, when mounted) and send a non-None hook result as the response, as on Flask.fastapiandquartalso run them on the WebSocket handshake. - #4075 Background callbacks without
cache_byno longer share a result between requests with equal inputs (unread Diskcache results now expire after a day, or afterexpirewhen set, even withcache_by), and callbacks with the same source no longer share a cache key.build_cache_keytakes a newcallback_keyargument. - #4075
dcc.Location(refresh=True).href,html.Area.hrefandhtml.Base.hrefnow blockjavascript:URLs likehtml.A. - #4075 Pages
path_templatematching no longer errors or backtracks badly on paths with a newline. - #4075 Add
configure_mcp_server(cache_by=..., cache_maxsize=...)so apps whose layout or callbacks depend on the user can keep the MCP server's cached tool descriptions and initial values per user (128 users by default,Nonefor no limit). - #4052 Fix callbacks of removed components still firing after a callback returns
Noneforchildren: the renderer now clears their paths. Fixes #4033. - #4027 Support
async defhook routes (dash.hooks.route) on all backends, stop hook routes from leaking the app context to the caller, and let hook routes and MCP read the request on thefastapibackend. - #4053 Fix callbacks being registered twice under a reloader (e.g.
uvicorn --reload) whenDash()is given an explicitnameor is built by an app factory called from the main module. Fixes #3912. - #3980 Fix the three
before_requesthooks (Dash._setup_serverand the pagesrouter_sync/router_async) publishing their "already done" guard flag before the setup work behind it had run. Under a multi-threaded WSGI worker such asgunicorn -k gthread(or under an ASGI worker for the async router), a second request arriving mid-setup could observe the flag already set, skip setup, then readregistered_paths/callback_map/ the pages router callback while they were still being registered - causing the first burst of component bundle requests after a restart to 500 withError loading dependency. "<lib>" is not a registered library, or the pages router to hitDuplicateCallbackwhen two workers raced past the guard. Each hook body now runs under a lock (threading.Lockfor the two sync hooks, anasyncio.Lockbound to the running loop for the async router) and only publishes the flag after all work completes. Fixes #3971. - #3944 Fix
dash.testingrunner backend detection for wrapped FastAPI/Quart servers so threaded Flask-only options are not passed to ASGI runners. - #3955 Unpin
seleniumin the testing requirements (was capped at<=4.2.0from 2022) and require>=4.11.0, so it can drive current stable Chrome via Selenium Manager and stop the widespread CI flakiness. - #3881 Speed up the renderer layout crawl (
crawlLayoutand its callers) by replacing curried-ramdapath/pathOrlookups with direct property access on the hot path: ~16% fasterPatch().append()into a large container, with no behavior change. - #3881 Fix pattern-matching (
MATCH/ALL/ALLSMALLER) callbacks getting quadratically slower as matching components grow; a new O(1) id->path index cuts anALLupdate over 400 components from ~580ms to ~140ms (~4x), with no app changes. - #3941 Fix the FastAPI and Quart backends opening a WebSocket connection on every page load even for apps with no WebSocket callbacks; the socket now opens only when actually needed. Fixes #3939.
- #3916 Fixed a regression where dragging multiple files into
dcc.Uploadwould upload only the first file whenmultiple=True - #3922 Fix
dcc.Input(type="number")stepper behavior when onlyminis set. - #3936 Use the proxied url as the Jupyter server url so
DASH_PROXYis honored by the external url and inline iframe in notebooks. Fixes #3401. - #3938 Fix
dcc.Patch()re-running the initial callbacks of components already on the page (including everyMATCH/ALLelement) and wiping their user-edited persisted values. Fixes #3681 and #3937 - #3960 Fix
dcc.Markdownnot rendering<dccLink />by using newer dependencies - #3881 Fix callback-returned children being unmounted and remounted on every update instead of reconciled in place, which reset component state and slowed large subtrees 3-4x (regression introduced in 4.2.0 by #3570); use
dash.remountto force a remount. Fixes #3846. - #3881 Fix components rendered as props (eg.
dcc.Dropdownoption labels,dcc.Tablabels) crashing or failing to update when the host subtree was replaced by a callback; out-of-treeExternalWrappercomponents now re-insert themselves and update in place. - #3881 Fix components that set their own initial state on mount (eg.
dash-bootstrap-componentsTabs) not applying it on first render, because descendant layout hashes were reset on the first fresh render (regression introduced in 4.2.0 by #3570). Fixes #3929. - #3948 Fix page getting progressively slower as callbacks append children.
- #3915 Fix MCP tool results erroring when a figure cannot be rendered to an image (eg. Kaleido without Chrome); the image is now skipped. Fixes #3914.
- #3621 Fix component generation crashing when the path to
extract-meta.jscontains a space. - #3895 Component generation errors from
extract-meta.jsnow name the file, prop path and line where they originate. Fixes #3362. - #4014 Disable autocomplete in DatePickerSingle and DatePickerRange inputs. Fixes #4009.
- #4007 Fix page loads failing with a 500 error on Windows when Dash is imported from an extended-length (
\\?\) path, as in JupyterLab Desktop. Package resource paths are now joined with the OS separator instead of/. Fixes #3002. - #4023 Fix extra callback registrations when an app runs from the parent directory:
python app/app.py, where the script shares its folder's name, registered its callbacks twice, andpython app/main.pyimported a siblingapp/app.pyas the parent package and registered its callbacks too (regression introduced in 4.4.1 by #3883). Fixes #4011. - #4057 Fixed background callbacks to update
set_propsinstead of replacing. Fixes #3104. - #3923 Fix a blank page and
SyntaxErrorin the browser when a dict component ID has a dot in one of its values. Fixes #3480. - #4074 Fix Pages passing percent-encoded path variables to
layoutandtitle, and the 404 page for paths with spaces or non-ASCII characters. Fixes #2360. - #4012 Fix
InvalidCallbackReturnValueraised when a no-output background callback's error handler returnsNone(or the job is cancelled), by treatingNonereturns from error handlers and the cancelled-job branch the same way:NoUpdate()only when there are outputs,Noneotherwise. Fixes #3628.