Skip to content

`v0.2.0`

Compare
Choose a tag to compare
@gbj gbj released this 25 Feb 21:03
· 2330 commits to main since this release

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.

  1. Synchronous: Serve an HTML shell that includes fallback for any Suspense. Load data on the client, replacing fallback 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.
  2. Out-of-order streaming: Serve an HTML shell that includes fallback for any Suspense. Load data on the server, streaming it down to the client as it resolves, and streaming down HTML for Suspense 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>)
  3. 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.
  4. 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.

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 in leptos_meta that let you change things like <html> lang and dir, and add a class to the <body>
  • Restoring on: event listeners on <Component/> nodes, e.g., <MyFancyButton on:click=.../> without needing to create an on_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() and Resource::with() now take a Scope as their first argument, i.e., resource.read() is now resource.read(cx). This is necessary for correct <Suspense/> behavior.
  • The Errors type has been modified to hide its internals and expose IntoIter directly. In 99% of cases this just means replacing references like errors.get().0.into_iter() with errors.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/> component view argument now takes a Scope as its first argument, i.e., a change from view=move |counter| { ... } to view=move |cx, counter| { ... }
  • The <ErrorBoundary/> component fallback argument now takes a Fn(Scope, RwSignal<Errors>) -> impl IntoView instead of Fn(Scope, Option<RwSignal<Errors>>) -> impl IntoView
  • NodeRef now takes NodeRef<T> instead of NodeRef<HtmlElement<T>>. We're also deprecating NodeRef::new(cx) in favor of create_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 using cargo-leptos or not. The site_address field is now named site_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 reexporting wasm-bindgen, web-sys, and js-sys so you may need to add them as dependencies to your Cargo.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 in leptos_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 SSR view 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 of build (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 remove log 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/> in todomvc 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() from redirect 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 implement IntoIter 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 into Resource::read() and Resource::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/> with local_resource (closes #562) by @gbj in #574
  • Ssr modes axum by @tanguy-lf in #575

New Contributors

Full Changelog: v0.1.3...v0.2.0