Product updates

What’s new in v1.1

With this release, we’ve enhanced stability and improved the room connection engine, enabling you to easily show the connection status to your users with a simple API.

What’s new in v1.1

Ensuring stability and a seamless realtime experience is crucial for collaborative applications. Liveblocks 1.1 not only introduces significant improvements in connection stability, but it also enables new APIs allowing you to build high-quality user experiences with minimal effort.

By completely rewriting our previous connection engine as a formalized state machine, we have taken a holistic approach to resolve all known bugs around connectivity and client recovery in edge cases. In this blog post, we’ll explore:

Connection stability enhancements

With the 1.1 release, we’re placing a strong emphasis on connection stability around edge cases, ensuring a reliable realtime experience for users. The rewritten connection engine, formalized and implemented as a state machine, streamlines the connection and reconnection process, greatly reducing the number of states we handle internally, making it easier to reason about the exact state of the Liveblocks connection at any given moment.

Simplified state chart of the new internal finite state machine

The stability enhancements extend to the collaborative aspect of applications, ensuring a smoother and uninterrupted experience that recovers quickly, minimizing disruptions and providing users with a seamless collaboration environment.

Features

In particular, we’ve made improvements to specific areas:

  • The client now restores connections much more quickly after your network becomes available again, or after waking up from a long sleep.
  • The client will respect 401 and 403 HTTP responses from your backend, and will take them as a sign that retrying will not have an any effect. This means that responding with a 401 or 403 in your auth endpoint will cause the client to stop trying to establish a connection altogether, reducing load on your application’s backend. Previously it would keep trying infinitely.

Rewriting the connection engine has also enabled us to create new APIs.

Connection status API

We’re now providing a clearer connection status API with simplified, and more intuitively ordered, status names. We’re also deprecating the old names, because they were tricky to understand, and confusing to work with.

Old vs new connection statuses

Previously, without learning about Liveblocks internals, it was not at all apparent when your app would be in each state, raising more questions than answers.

  • What does open mean?
  • When is my app unavailable, and is it before or after failed?
  • What’s the difference between authenticating and connecting?

In Liveblocks 1.1, you can subscribe to a new status subscription, which uses a fresh new set of states: initial, connecting, connected, reconnecting, disconnected.

With the status subscription, it’s immediately apparent which state your app starts in, and the order in which each state occurs. And as an added bonus, you can now also distinguish between connecting and reconnecting, which is an important difference when building real world applications.

Building a status badge

With this addition, it’s now easier than ever to create a connection status badge, and display the current state of your app.

Connected status badge
Connected status badge
Reconnecting status badge
Reconnecting status badge

To build this in React, import the new useStatus hook to return the current online status.

import { useStatus } from "../liveblocks.config";
export function Status() { // "initial" | "connecting" | "connected" | "reconnecting" | "disconnected" const status = useStatus();
return <StatusBadge type={status} />;}

We’ve also added a JavaScript equivalent to this hook to our client package for other framework users, room.subscribe("status").

room.subscribe("status", (status) => {  // "initial" | "connecting" | "connected" | "reconnecting" | "disconnected"  console.log(status);});

Lost connection API

When a user loses connection to your app, for example because of a poor Wi‑Fi signal, it’s important to let them know about it. You can do this by displaying a toast notification, however, you don’t have to let them know immediately.

Reconnecting status toast
Reconnecting status toast
Reconnected status toast
Reconnected status toast

Because Liveblocks continues working after a connection interruption, and then synchronizes after reconnecting, it’s safe to ignore brief connection hiccups, and allow the user’s device a few seconds to reconnect. Only after this period is it necessary to consider a connection “lost”. With this in mind, we’ve added another new feature.

Lost connection listener

In Liveblocks 1.1, you can subscribe to a new “lost connection” event, making it far simpler to create these toast notifications and handle reconnection behaviour. What’s important about our new subscription, is that we handle the behaviour for you:

  • Short connection issues are ignored, this event is for when a more serious problem has occurred.
  • This event is only emitted after a user has connected and then had a problem.
  • If nothing goes wrong, your user will never receive this event.

Implementing this was possible previously, but a deep understanding of our internals was required to create a reliable implementation.

Building toast notification warnings

Below is a video recording of the open-source Connection Status example we put together to demo the sort of experience you can create with those APIs.

To build toast notification warnings in React, import the new useLostConnectionListener hook alongside your favorite toast notification library, for example react-hot-toast.

import { useLostConnectionListener } from "../liveblocks.config";import toast, { Toaster } from "react-hot-toasts";
export function LostConnectionToasts() { const toastId = useRef<string>();
useLostConnectionListener((event) => { if (event === "lost") { toastId.current = toast.loading("Trying to reconnect…"); }
if (event === "restored") { toast.success("Reconnected!", { id: toastId.current }); }
if (event === "failed") { toast.error("Could not reconnect, try refresh", { id: toastId.current }); } });
return <Toaster />;}

We’ve also added a JavaScript equivalent, room.subscribe("lost-connection").

room.subscribe("lost-connection", (event) => {  // "lost" | "restored" | "failed"  console.log(event);});

Alongside this addition, we’ve also made a change to others.

Change to others

Previously, others would be reset as soon as a reconnect would happen under the hood, even if that reconnect happened quickly. This meant that even if a network interuption lasted just milliseconds, live avatars or other presence indicators would have a flash of unrendered content, before reappearing. We’ve fixed this.

In Liveblocks 1.1, others will ignore short reconnections, similar to the lost connection API, and will only reset if a noticeable problem occurs, preventing any unwanted user interface flashes.

Configuring the lost connection timeout

It’s possible to configure how quickly you’d like to inform your users about problems reconnecting using the new lostConnectionTimeout client option. The default value is 5 seconds, and we recommend setting it between 3 and 15 seconds.

import { createClient } from "@liveblocks/client";
const client = createClient({ // Set timeout in milliseconds lostConnectionTimeout: 5000,
// Other options // ...});

This enhanced user awareness improves transparency, empowers users to take appropriate actions, and contributes to an overall positive user experience.

Deprecated APIs

While we’ve carefully taken care of every edge case we could think of, we have introduced some behavioral changes to fix bugs and make the whole experience more stable. As a result the following API are being deprecated as part of 1.1:

  • room.subscribe("connection")
  • room.getConnectionState()

DevTools offline support

Before Liveblocks 1.1, if your connection was lost, you’d see our DevTools jump back to the “loading” state, making it impossible to observe storage and presence while the client was trying to reestablish a connection. This is no longer the case!

Connected DevTools status
Connected DevTools status
Reconnecting DevTools status
Reconnecting DevTools status

Now, when reconnecting, both storage and presence remain introspectable, so you can actually see how they’re behaving while not connected to the Liveblocks servers. This more accurately reflects the way the client actually handles data (all the storage and presence data still exists in the local client).

Contributors

Huge thanks to everyone who contributed and specifically to Chris Nicholas for the feedback and help testing this out. Also a big shout out to our incredible community that keeps jumping in to help us improve our infrastructure! Keep checking out the changelog for the full release notes – see you next time!