Security
- ⚠️ Harden against
X-Forwarded-Prefixreflection and clarify the security documentation (#6124 by @evnchn, @falkoschindler)
New features and enhancements
- Add a custom keybindings API to the
ui.codemirroreditor (#6000 by @Jepson2k, @evnchn, @falkoschindler) - Declare the page language via
<html lang="...">whenui.run(language=...)is set, and stop Quasar from forcingen-USotherwise (#5811 by @evnchn, @falkoschindler) - Introduce
ui.markdown.default_extrasto configure Markdown extras globally (#5548, #5610 by @tomsquest, @evnchn, @falkoschindler) - Simplify the multipart spool-size lookup now that Starlette ≥ 1.0.1 is required, and respect an explicit
spool_max_size = 0(#6102 by @falkoschindler, @evnchn)
Bugfixes
-
Fix character loss in
ui.input(and other value elements) on high-latency connections by preserving client-originated values during element updates (#5185, #6104 by @Xitod, @samuller, @evnchn, @falkoschindler) -
Fall back to polling when the WebSocket cannot connect, fixing the endless reload loop on iOS 26 Safari over plain HTTP (#5802, #6103 by @michaeljandrews, @evnchn, @falkoschindler)
-
Fix native window close hanging or failing to shut down the app — on Windows, after a hot reload, and when
run.cpu_boundwas used (#5443, #5845, #6106, #6111, #6131, #6132 by @MaidScientistIzutsumiMarin, @trivedihoney, @Mick235711, @trivedihoney, @chidoziemanagwu, @evnchn, @falkoschindler) -
Fix
ui.sub_pageswildcard routes not re-rendering on client-side navigation, and reject unsupported route patterns (#6090, #6092 by @JoelBender, @falkoschindler, @evnchn)Breaking change: Route patterns that previously failed silently (e.g.
'/{_:path}','/{name:path}') now raise aValueErroratui.sub_pages(...)/.add(...). These never matched anything before, so only already-broken routes are affected; useshow_404=Falsetogether withPageArguments.remaining_pathfor wildcard routing instead. -
Fix a selection error when changing
ui.selectoptions inside an "input-value" handler (#4420, #6100 by @platinops, @VedantMadane, @falkoschindler, @evnchn) -
Fix
ui.select(with_input=True)dropping itshtml_id, which broke tooltips (#6114, #6116 by @rolfn, @python-and-novella, @evnchn, @falkoschindler) -
Fix
ui.skeleton'sanimation_speedbeing sent as milliseconds instead of seconds (#6107, #6110 by @python-and-novella, @evnchn, @falkoschindler) -
Fix
ui.interactive_imageclick coordinates when a stream changes its resolution (#6122, #6123 by @LeBoozer, @evnchn, @falkoschindler) -
Fix GLTF models in
ui.scenebeing overwritten with the default material at startup (#6118, #6125 by @fabian0702, @evnchn, @falkoschindler) -
Fix an infinite reload loop when an async page build exceeds
response_timeout, showing a terminal error page instead (#6126, #6127 by @evnchn, @falkoschindler) -
Fix the
run.cpu_bound/run.io_boundreturn type toR | None, surfacing the latentNonethey already return on cancel/shutdown (#5925, #6056 by @calebgregory, @evnchn, @falkoschindler)Note: This is a type-level change only; runtime behavior is unchanged. mypy may now flag code that typed the result as non-optional
R— these are surfaced latent bugs, not regressions. NiceGUI 4.0 will raiseCancelledErrorinstead of returningNone.
Documentation
- Improve AI-agent detection in Markdown content negotiation so agents reliably receive Markdown docs (#6109, #6113 by @jwinpbe, @evnchn, @falkoschindler)
- Improve
app.storagedocumentation clarity and fix inconsistencies (#5717, #5719 by @phifuh, @evnchn, @falkoschindler) - Reserve
NOTE:comment markers for drawing special attention (#6101 by @falkoschindler, @evnchn)
Infrastructure
- Add a request check to the startup smoke test so request-time regressions no longer ship green (#6079, #6084 by @evnchn, @SSDWGG, @falkoschindler)
- Remove the redundant CI Gate run on
pushtomainnow that the merge queue already validates every commit reachingmain, speeding up releases (#6136 by @falkoschindler, @evnchn) - Bump actions/checkout from 6 to 7 (#6121 by @dependabot, @evnchn)
Special thanks to our top sponsors DiscoLike Inc. and Lechler GmbH ✨
and all our other sponsors and contributors for supporting this project!
🙏 Want to support this project? Check out our GitHub Sponsors page to help us keep building amazing features!