v0.2.0
v0.2.0
is an incremental change over 0.1.x
. There are a few small things that have been breaking changes over the last two months, one big new feature, and a lot of small improvements and changes.
Async Rendering and In-Order Streaming
The biggest new feature of 0.2.0
that requires explanation is support for async
rendering and in-order streaming, which you can activate via the new ssr
prop on a <Route/>
. (See the ssr_modes
and ssr_modes_axum
examples.)
With this new feature, Leptos now supports four different ways to render HTML that contains async
data loaded under <Suspense/>
. You can opt in to one or the other on a per-route basis.
- Synchronous: Serve an HTML shell that includes
fallback
for anySuspense
. Load data on the client, replacingfallback
once they're loaded.- Pros: App shell appears very quickly: great TTFB (time to first byte).
- Cons: Resources load relatively slowly; you need to wait for JS + WASM to load before even making a request.
- Out-of-order streaming: Serve an HTML shell that includes
fallback
for anySuspense
. Load data on the server, streaming it down to the client as it resolves, and streaming down HTML forSuspense
nodes.- Pros: Combines the best of synchronous and
async
, with a very fast shell and resources that begin loading on the server. - Cons: Requires JS for suspended fragments to appear in correct order. Weaker meta tag support when it depends on data that's under suspense (has already streamed down
<head>
)
- Pros: Combines the best of synchronous and
- In-order streaming: Walk through the tree, returning HTML synchronously as in synchronous rendering and out-of-order streaming until you hit a
Suspense
. At that point, wait for all its data to load, then render it, then the rest of the tree.- Pros: Does not require JS for HTML to appear in correct order.
- Cons: Loads the shell more slowly than out-of-order streaming or synchronous rendering because it needs to pause at every
Suspense
. Cannot begin hydration until the entire page has loaded, so earlier pieces
of the page will not be interactive until the suspended chunks have loaded.
async
: Load all resources on the server. Wait until all data are loaded, and render HTML in one sweep.- Pros: Better handling for meta tags (because you know async data even before you render the
<head>
). Faster complete load than synchronous because async resources begin loading on server. - Cons: Slower load time/TTFB: you need to wait for all async resources to load before displaying anything on the client.
- Pros: Better handling for meta tags (because you know async data even before you render the
The mode defaults to out-of-order streaming. For a path that includes multiple nested routes, the most
restrictive mode will be used: i.e., if even a single nested route asks for async
rendering, the whole initial
request will be rendered async
. (async
is the most restrictive requirement, followed by in-order, out-of-order, and synchronous.)
Because you have the ability to opt into these different modes on a per-route basis, you can choose the rendering strategy that is best for you—not only for your app in general, but for any given page.
Other Features and Improvements
- New
<Html/>
and<Body/>
components inleptos_meta
that let you change things like<html>
lang
anddir
, and add aclass
to the<body>
- Restoring
on:
event listeners on<Component/>
nodes, e.g.,<MyFancyButton on:click=.../>
without needing to create anon_click
prop - Adding a
<Redirect/>
component in the router that works during client-side navigation or server-side rendering Children
,AttributeValue
, and other type aliases to make it easier to accept a variety of types in your components- Experimentation with new docs using CodeSandboxes and an expanding set of tutorials
- So, so, so, so many bugfixes, typos, docs improvements, and small changes by many, many, many members of the community. Thanks to you all!
Breaking Changes Since 0.1.3
Resource::read()
andResource::with()
now take aScope
as their first argument, i.e.,resource.read()
is nowresource.read(cx)
. This is necessary for correct<Suspense/>
behavior.- The
Errors
type has been modified to hide its internals and exposeIntoIter
directly. In 99% of cases this just means replacing references likeerrors.get().0.into_iter()
witherrors.get().into_iter()
- Most of the methods on various signal types have been moved into traits instead. This should not cause any actual changes to the way you use them, and if you are accustomed to
use leptos::*
you probably won't notice the difference; if you are manually importing types you will need to import the signal traits as well. - The
<For/>
componentview
argument now takes aScope
as its first argument, i.e., a change fromview=move |counter| { ... }
toview=move |cx, counter| { ... }
- The
<ErrorBoundary/>
componentfallback
argument now takes aFn(Scope, RwSignal<Errors>) -> impl IntoView
instead ofFn(Scope, Option<RwSignal<Errors>>) -> impl IntoView
NodeRef
now takesNodeRef<T>
instead ofNodeRef<HtmlElement<T>>
. We're also deprecatingNodeRef::new(cx)
in favor ofcreate_node_ref(cx)
to follow the same pattern as everything else in the framework.- We've finally achieved full consistency between
cargo-leptos
and the server integrations whether you're usingcargo-leptos
or not. Thesite_address
field is now namedsite_addr
; the compiler should actually prompt you correctly for this one. - The current Leptos global namespace is polluted with a huge number of types and reexports, making it harder to find things in docs and adding compile-time overhead. If you're used to
use leptos::*
you may need to manually import a few additional types. We're also no longer reexportingwasm-bindgen
,web-sys
, andjs-sys
so you may need to add them as dependencies to yourCargo.toml
- APIs to modify status code and headers in HTTP responses are now synchronous, making them easier to set in components
Complete CHANGELOG
- Add
Children
type alias by @gbj in #403 - Fix boolean attributes in
view
macro fast-path SSR by @gbj in #408 - Add
<Html/>
and<Body/>
components inleptos_meta
by @gbj in #407 - Minor: Bump typed-builder from 0.11 to 0.12. by @martinfrances107 in #409
- Escape and tokens in documentation markup. by @martinfrances107 in #410
- fix: correct types for top-level
<option>
and<use>
in SSRview
macro by @gbj in #416 - Switch RwLock to parking_lot so they are no longer async by @benwis in #414
- Add leptos_routes functions for integrations by @b4-io in #415
- Fix issues with attribute names in SSR by @gbj in #418
- Implemented update_returning for StoredValue by @thestarmaker in #419
- Update ErrorBoundary to use miette::Diagnostic instead of Error, and various other tweaks by @benwis in #401
- Fix some small issues in
axum_errors
example by @gbj in #424 - fix: Make all fragment rendering lazy (closes #299 and #421) by @gbj in #425
- fixes cx not found on components marked with #[component(transparent)] by @jquesada2016 in #423
- Several Minor Updates on Examples by @Indrazar in #427
- Make
RouteDefinition
public by @gbj in #430 - docs: Document
inner_html
attribute by @gbj in #429 - chore: switch examples to
check
instead ofbuild
(for CI) & add missing examples by @gbj in #437 - Fix top-level SVG elements in SSR by @gbj in #435
- fix: correct behavior of
<Show/>
by @gbj in #436 - Dedup from_str implementations for Env by @g-re-g in #426
- leptos-server: Removed unused dependency on log, linear-map and rmp-serde. by @martinfrances107 in #439
- leptos_macro: Machete - Removed unused deps. by @martinfrances107 in #441
- router: Machete - Removed unused deps. by @martinfrances107 in #442
- use latest tokio in leptos_axum by @Gentle in #443
- fix: successfully pass context to nested routes via
<Outlet/>
by @gbj in #447 - feature: allow
on:
event listeners on<Component/>
nodes by @gbj in #448 - fix: update leptos dependencies paths to the workspace by @TurboTobias in #449
- fix:
leptos_router
hydration issues by @gbj in #450 - Clippy: "{input} is not a supported environment." by @martinfrances107 in #451
- fix: stack overflow in with nested outlet (closes #452) by @gbj in #453
- fix: typo in
leptos_config
description by @odiseo0 in #455 - docs: add new
Children
types to macro docs by @gbj in #454 - Derive debug for params struct in server macro by @g-re-g in #458
- perf: further reduce WASM binary size by ~5-7% by @gbj in #459
- Fix #457 by @Threated in #460
- docs: add note about optional
fallback
in<Show/>
(closes #406) by @gbj in #463 - impl Default for MaybeSignal by @ModProg in #464
- feature: add isomorphic
<Redirect/>
component (closes #412) by @gbj in #466 - Add simple icon logo by @underscorefunk in #468
- error on non meta input for prop attribute by @ModProg in #469
- fix: don't override element event listeners with component event listeners by @gbj in #470
- fix: fix
node_ref
in SSR by @gbj in #471 - Convert site_address to site_addr by @benwis in #462
- impl From<&str> for MaybeSignal by @g-re-g in #472
- fix: correct out-of-order streaming behavior (closes #473) by @gbj in #475
- fix:
cargo doc
in projects using#[server]
by @gbj in #476 - fix: adding/removing errors from
<ErrorBoundary/>
by @gbj in #478 - Experiments in new tutorial/guide format with integrated CodeSandboxes by @gbj in #375
- remove unnecessary
"openssl"
feature from Actix examples by @gbj in #480 - Better styling for router related components by @Threated in #477
- fix: errors on 404 page in
axum_errors
example by @gbj in #485 - Minor: Clippy router now uses types OnFormData and OnResponse. by @martinfrances107 in #484
- fix: correct behavior for
inner_html
in SSR by @gbj in #487 - fix: typed route params with
#[derive(Params)]
by @gbj in #488 - Fix node ref generics by @jquesada2016 in #481
- fix: fix
debug_warn
behavior in reactive crate and removelog
dependency by @gbj in #491 - change: add
Scope
to view function in<For/>
to avoid memory "leak" by @gbj in #492 - fix: error boundary hydration by @gbj in #494
- Suspense: removed unused .clone() call. by @martinfrances107 in #486
- examples: remove unused
index.html
by @gbj in #497 - Allow literal string as class in view macro by @g-re-g in #500
- fix: proper disposal of nested route scopes by @gbj in #499
- workspace
rustfmt
by @jquesada2016 in #483 - apply new formatting everywhere by @gbj in #502
- Docs improvements by @gbj in #505
- fix:
<For/>
intodomvc
example by @gbj in #504 - docs: add docs on testing (closes #489) by @gbj in #508
- chore: reorganize module exports and reexports by @gbj in #503
- Typos and a small cleanup by @g-re-g in #509
- fix: import in
leptos_dom
and add Wasm build to CI for regressions by @gbj in #510 - fix: SSR export in Wasm mode by @gbj in #512
- CI: add Wasm testing by @gbj in #511
- In Axum Integration Remove unwrap() from redirect function by @Indrazar in #513
- remove
.unwrap()
fromredirect
in Actix integration by @gbj in #514 - version:
0.2.0-alpha
by @gbj in #515 - leptos_dom erros.rs remove() does not need to be generic. by @martinfrances107 in #516
- fix: correct namespace for
Unit
in empty views (closes #518) by @gbj in #520 - Reexport
web-sys
event types to make it easier to type handlers by @gbj in #521 - Identify CSS to reload from the href by @akesson in #524
- change: tweak API of
Errors
and implementIntoIter
by @gbj in #522 - fix: top-level SVG in
view
macro with new exports by @gbj in #525 - feature: reintroduce limited template-node cloning w/
template
macro by @gbj in #526 - fix: hydration IDs for elements following
<Suspense/>
(closes #527) by @gbj in #531 - feature: in-order streaming and
async
rendering by @gbj in #496 - fix compile of leptos dom by @seanaye in #535
- Signal traits by @jquesada2016 in #490
v0.2.0-alpha2
by @gbj in #539- fix: building
leptos_reactive
in release mode by @gbj in #540 - 533 by @jquesada2016 in #538
- fix(examples): hackernews_axum styles href by @ApplY3D in #536
- revert PR #538 by @gbj in #544
- fix: more work on hydration IDs with
<Suspense/>
by @gbj in #545 - change: pass
Scope
intoResource::read()
andResource::with()
by @gbj in #542 - document typo by @chrislearn in #553
- Fix typo in hydration.rs by @eltociear in #552
- Fix issue with redirects in server fns creating multiple Location headers by @benwis in #550
v0.2.0-beta
by @gbj in #557- doc: fix button name in parent_child example by @tversteeg in #555
- docs: add example of
<ButtonC on:click/>
syntax by @gbj in #558 - docs: add
create_resource
,<Suspense/>
, and<Transition/>
by @gbj in #559 - fix: remove unnecessary log by @gbj in #560
- fix: issue with local resources blocking
<Suspense/>
fragments by @gbj in #561 - feature: add class option to Html component by @polarmutex in #554
- feat: viz integration by @fundon in #506
- fix:
transition
fallback (closes #562) by @gbj in #563 - fix:
<details>
toggle event does not bubble (issue #565) by @gbj in #566 - Relax Eq to PartialEq for create_slice() by @godstail in #570
- Make meta link as output correct attribute html by @SleeplessOne1917 in #573
- Macro
panic
hygiene by @remkop22 in #568 - Add example: Login with API token (CSR only) by @flosse in #523
- fix:
<Transition/>
withlocal_resource
(closes #562) by @gbj in #574 - Ssr modes axum by @tanguy-lf in #575
New Contributors
- @b4-io made their first contribution in #415
- @thestarmaker made their first contribution in #419
- @g-re-g made their first contribution in #426
- @TurboTobias made their first contribution in #449
- @odiseo0 made their first contribution in #455
- @Threated made their first contribution in #460
- @underscorefunk made their first contribution in #468
- @seanaye made their first contribution in #535
- @ApplY3D made their first contribution in #536
- @chrislearn made their first contribution in #553
- @eltociear made their first contribution in #552
- @tversteeg made their first contribution in #555
- @polarmutex made their first contribution in #554
- @fundon made their first contribution in #506
- @godstail made their first contribution in #570
- @SleeplessOne1917 made their first contribution in #573
- @remkop22 made their first contribution in #568
- @tanguy-lf made their first contribution in #575
Full Changelog: v0.1.3...v0.2.0