Asynchronous UX

"Please do not close or leave this page" may send shivers down your spine, but coding the proper UX flow for async might make you question your daily job. How can we properly handle UX for asynchronous code in highly responsive applications? Let's explore how introducing asynchronous code creates a challenge for UX.

Rate this content
Bookmark
Video Summary and Transcription
The video discusses the importance of Asynchronous UX in React, focusing on techniques to improve user experience in single-page applications. It highlights the use of progress indicators and skeleton screens to enhance web design loading pages asynchronously. The talk addresses handling asynchronous UI challenges, such as flickering effects and backend errors, by introducing delays and categorizing errors for better management. It emphasizes the significance of implementing idempotency keys in web applications to prevent duplicate actions, especially in critical operations like payments or bookings. The video also explores the concept of optimistic updates, where actions are assumed successful to maintain a responsive UI, and the potential issues it might cause if subsequent actions fail. Techniques for managing long-running actions, such as providing real-time feedback and disabling UI elements, are discussed to ensure a smooth user experience.

This talk has been presented at React Advanced 2021, check out the latest edition of this React Conference.

Available in Español: UX Asincrónico

FAQ

Implementing skeleton UX can be challenging as it requires careful design to match the layout of the loading data accurately. It must also be synchronized with the actual content to avoid mismatches and can be complex to implement effectively across different components.

To prevent flickering effects in data fetching, developers can introduce a delay before showing progress indicators for fast connections, use skeleton screens to show data layout during loading, and manage asynchronous operations carefully to ensure consistent and smooth updates.

An idempotency key is a unique identifier used to prevent duplicate actions in web applications, such as multiple submissions. It ensures that repeated requests for the same action result in only one processed action, which is crucial for operations like payments or bookings.

Handling errors and empty states is crucial as it directly impacts user satisfaction and trust. Providing clear messages and recovery options when errors occur or no data is available enhances the user experience by making the application more robust and user-friendly.

Developers can handle backend errors by categorizing them into user-fixable or server-side issues, providing appropriate feedback and recovery options, and considering automatic retries or redirects depending on the error type to enhance reliability and usability.

Developers can manage long-running actions by providing real-time feedback through progress indicators, disabling UI elements to prevent repeated actions, and implementing optimistic updates or timeouts to inform users about the action's progress and maintain a responsive interface.

Asynchronous UX in React refers to user interface patterns that handle the asynchronous nature of web applications, such as waiting for server responses or handling data fetching delays without blocking user interactions.

Single-page applications can enhance user experience by implementing features like progress indicators, skeleton screens, and handling error states to provide feedback during data fetching, thus improving the perceived responsiveness and interactivity of the application.

1. Introduction to Asynchronous UX#

Short description:

Today, I'll be talking about Asynchronous UX with React and single-page applications. I'll cover scenarios you'll encounter in your daily job and provide code examples and UX examples. The key takeaway is the importance of building this kind of UX for users and the development cost.

Hi, thank you for joining today's session. My name is Tony and today I'll be talking to you about Asynchronous UX with React and single-page applications. When we say that the web is asynchronous, we are referring to the underlying request-response nature of the web, where a response from the server might take some time to arrive. Traditionally, applications built with server-side rendering in mind were handled by the browser. When we build the same application as a single-page application, we have to build new affordances for the user because the browser can't handle them for us. In today's session, I'm going to go over certain scenarios you will encounter in your daily job and try to address them with code examples and UX examples. At the end of the talk, I hope you'll take away from it that it's very important to build this kind of UX for the users and how much it will cost in terms of development.

2. Exploring Data Fetching and UX#

Short description:

Before we begin, let's divide this topic into two areas: read-only data patches and user-initiated actions that change the server state. When navigating the page, fetching data may take some time. To improve the UX, we can add a progress bar or employ skeleton UX. Building more consistent UX can be complex, especially when multiple components have their own proxy indicators. To avoid flickering effects, we can introduce a delay before showing the progress indicator. Let's look at a naive example of code for a page and explore how it can be improved.

Before we begin, I just want to divide this whole topic in two different areas. The first area deals with read-only data patches, and the second area is user-initiated actions that change the state of the server, basically doing form submissions while the queries are page navigations.

Let's talk about queries. So whenever you navigate the page, you might fetch some data. In this naive example, when we navigate to a page, we will fetch the data and then display it to the user. This is a happy scenario where the data arrives somewhat quickly, but depending on the network load, the server load, or the user data, waiting for the data to arrive might take some time. While the user is waiting, we kind of want to inform them that they have to wait in case there are no results. We want to tell them there are no results. If there's an error, we want to tell them that there was an error and what they can do about it.

To improve this UX a bit, we want to add a simple progress bar. This progress is indeterminate because we don't know when it will end, and the user might just want to stick around and wait for the data to arrive. To improve on this very simple progress indicator, we might want to employ skeleton UX. Now skeleton UX looks like the data is going to replace. Basically, this stops flickering effect from happening, because the users will see the outline of the incoming data, and then when the data arrives, it basically just replaces hopefully in place. Unlike progress indicator, skeleton UX is much, much harder to build and can quickly go out of sync with the components they're trying to mimic. So be wary of the complexities involved in building them.

For a bit more complicated page, you can see that when the data is there, you might want to have partial updates with fetching more data. You might want to have different ways of fetching data which might yield different data sizes. So in this case, we can see that sometimes you get little data, sometimes you get no data, sometimes you get an error. And when you have data fetching, you kind of want to reuse this UX. As you can see, building more consistent UX requires some explaining, and you can imagine how much more complicated the code might be. When we build components in our applications, we might want to focus too much on a single component, so each component has its own data fetching and its own proxy indicator. What can happen is that we can quickly end up in a situation where multiple components on the same screen have their own proxy indicators, and then we have this flickering effect as different components have data arriving in a different order. Also, when we have very fast servers, it can be annoying because of the flickering effect because data will arrive very quickly and then the users will see the progress indicator for just a brief time. So to improve that experience, we might want to introduce some kind of delay before showing the progress indicator, so only showing the progress indicator when the data takes a long time to arrive.

Let's take a look at a very naive example of how the code would look for a page. Regardless of whether or not you use React query or Apollo or something similar, your component might look like something like this – you fetch data and you display it inside your UI. Now, can we do better than this? Of course we can, but it will require additional work and it will require a different type of work. So let's take a look at how much more complicated the code can get. On the left side, we can see the naive example from before, and on the right side we'll keep improving it by handling different scenarios that we've shown in the previous demos.

3. Adding Progress Indicators and Handling Errors#

Short description:

The first thing to add is the progress indicator. It can be implemented as a top-level loading indicator or inline below the H1. Handling errors, empty states, and skeleton loaders can greatly improve the UX. Introducing a delay and preventing the display of multiple progress indicators are important. Handling backend errors depends on the application, including user fixable errors, server load issues, general failures, and network connection problems. Improving the UX for long running responses is also crucial.

So the first thing we want to add is the progress indicator. Now, that is kind of straightforward, we just have some kind of flag saying that, yeah, loading is being done, in which case we show the loading UI. Now, you can already see that this can be done in two different ways, either as a top-level loading indicator or you can actually inline below the H1 and thus have a bit more intrusive loading indicator. Your opinions influence the way you implement this. If we want to handle errors, we have to add yet additional code, and you can see that this displaying of the error might also change location and be a bit more intrusive, thus making this pattern harder to extract in a higher-order component.

You can also handle, for example, the empty state, which, as you can see, it goes a bit more intrusive in the overall structure of the page. So as you can see, adding support for many UX scenarios will have a different impact on your code. And sometimes it will be hard to squint and see how we can actually isolate this in a higher-order component that can be reusable across the application. So there is always more that we can add to the page that can improve the UX. So empty states generally improve situations where the application is brand new for the user, basically they have no data, or when they are, for example, searching for stuff that doesn't exist. So in this case, we want to actually always show the results to the user, or tell them that there are no results. That improves the UX tremendously.

Skeleton loaders are a much better UX over the regular, simple progress indicators, but they require a bit more development time, they can quickly go out of sync with a target UI that they will replace. So take special care about introducing skeleton UIs because of the complexities they bring. Progress indicators, again, just a naive boolean, don't show, might not be enough. So we want to introduce some kind of delay to prevent the flickering effect. And also we want to prevent this forest of progress indicators, and only keep the indicators for something that's really, really slow. We haven't really talked much about how to handle backend errors, because it depends on the application. There are different kinds of errors. There are the user fixable errors, basically they can do something else. There is the retry later because the server has a tremendous load. So we can't really handle the request right now. Or there can be a general failure where we redirect the user to use the support, and basically asks us what went wrong. There's also a special case about network connection issues. For example, if you're in high density urban area or going out of reach, like in a tunnel or just in a rural part of the country, you might actually drop connection or have this intermittent connection issues. In that case the UI must or should handle these cases by showing to the user that right now data cannot be fetched and they should either refresh the full page or display a button where they can retry the fetch themselves when the connection recovers. You also might want to improve the UX for the long running responses. Sometimes waiting for more than five seconds will just look bad for the user. They will not know what to do. They might want to refresh the whole page.

4. Handling User-Initiated Actions and Side Effects#

Short description:

They don't know what went wrong. In the side effectful area, we want to handle user-initiated actions and inform the user about the action's progress and any issues. We also need to consider side effects in the application. Let's look at a demo of a responsive UI where a button click triggers an action and provides feedback. However, double clicking can cause issues, and we need to handle them properly.

They don't know what went wrong. So you might want to actually change the text message after a certain while or do different kinds of improvements.

If we take a look at the second area, the side effectful area, we want to see how to handle the user initiated actions. Now, because the user initiated an action, unlike navigating, they want to know that the action is being handled. They want to know if the action has been done handling, are there any issues. In case of an issue, is there anything the user can do or is just a general failure.

We also want to take a look are there any side effects in that application because depending on what the user did, it can change. So let's again take a look at some demos. In this case, we're going to take a look at a very simple attempt at building a responsive UI. So when you click a button, after a while you get a success message saying the action has been completed and the user can continue doing whatever they were doing. However, you can see that this is a really sad experience because the user can double click and then we don't know what the server side can do in that case. We might create double entries or something similar.

5. Handling Errors and Idempotency#

Short description:

In the case of an error, you never know what the error action is. A well-behaving button disables itself to prevent double submission, displays a progress indicator, and informs the user when the action is done. To improve user experience, we can implement an idempotency key to prevent duplicate actions. Single-page applications may cause side effects if the user navigates away before an action completes.

In the case of an error, you never know what the error action is. Did we misconfigure click handler? Was a network drop? Did the server respond with a 500? We don't know. And we want to inform our users that there's been something wrong. A well-behaving button, in this case, disables itself so that it prevents double submission. It also displays a progress indicator. And also when it's done, it informs us that something has happened. This is the example we want to strive for.

Some applications, when you're doing very advanced things, might want to tell you that please don't leave this page. Please wait until the operation is done. This might take some time. You never know how much. In a happy pet scenario, this will take a second, and you're done. However, if this page stays on and on, the user might be confused or worried. And they're not really sure if they should leave the page, what happens if they refresh. And that can yield subpar user experiences.

Now, because this is an example of booking tickets known to everyone, we want to see what we can do to improve the user experience. So let's take a look at this button. Let's say it takes a long time to execute and during this time something's happening in the server. After a while, the result comes back and we book it. Now I'm going to do something different. I'm going to click on a button and refresh the page. This is just basically destroying the context. When we go back to the page and we click the same button, it's done almost immediately because the server-side response, yes, the operation you requested was actually done before and this is the result I would have sent the previous time.

How would we do something like this? The idea is very simple, a bit more hard to execute for such important actions that really should not happen twice. We implement something called idempotency key. Basically, we generate a random key, assign it to the action and then we remember this key in local storage and when sending the request to the server, we send the same key. On subsequent requests, the server will duplicate the request and actually respond with the previous response, thus not doing the same operation twice. This is very important if you want to handle, for example, payments or any kind of limited resources in the real world because you don't want to do it twice. You don't want to order two things or pay for the same thing twice.

Now, because single-page applications are not built the same way as server-side renders, what can happen is that when you perform an action on one screen and if it takes too long the user can leave and go to another page and then when the action completes, the response will come and side effects might happen that will potentially cause bugs.

6. Handling Component Unmounts and Side Effects#

Short description:

When we click on a button and then leave to a different page, we may still see the same alert. However, if we try to modify React UI, we'll get a warning about a memory leak. To handle this, we need to remember when a component unmounts and avoid performing side effects.

So, let's take a look at this example. When we click on this button, an action done will be said that this was completed. If we click and then leave to a different page because nothing prevents us from leaving, we can still see that we have the same alert. Now, this is just illustrative. If we try to do something like set state or try to modify React UI, we'll actually get the warning in the console saying that we have a memory leak. We should not do anything because the component has been unmounted. To properly handle this, we need to kind of remember that when component unmounts, we actually wanna know that the component was unmounted and actually not perform the side effects. This is just illustrative saying that, yes, we understand this component knows it's been unmounted and thus, it should not actually perform the side effects.

7. Handling Multiple Actions and UX#

Short description:

One final thing to consider in rich client-side applications is the handling of multiple actions on the same screen. It's important to ignore previous requests and only take into account the last sent request. Adding code to improve the user experience can become intrusive, especially when handling errors. Field level validation, blocking input while waiting, and handling network issues are important considerations. Blocking actions prevent users from leaving, while non-blocking actions display toasts when complete. Having a notification center and preventing double submissions are also good practices.

One final thing that can happen with a very rich client-side applications is that when you have a series of actions on the same screen, which render in the same UI but might take a different time to respond from the server. For example, filtering data might have different response times depending on how much data needs to be processed on the server. If the user clicks around many different times, you can see that the responses come out of we don't show the last clicked action result, we actually show the last result that arrived, which might actually be the one that was sent earlier. So special care must be taken to basically ignore all previous requests and only take into account the last sent request.

Let's take a look at some of the code. So on the left side I'm going to keep the very simple, very direct implementation of a handling submission. And on the right side I'm going to add more code to improve the UX and we'll see how much bigger the code becomes and how much more intrusive this UX becomes. So the first thing, we're going to add a state for whether or not we're submitting or not. As you can see, we need to state variable, we need to properly handle it when it starts, when it stops. We need to display the UI that shows that the action is being performed. And then we also want to disable the button. If we want to handle errors it gets even more intrusive because we are touching already touched code and you can see that the UI is also being changed in a very inline way. It's really hard to isolate this in a higher level component.

And as before, there is always more we can add. We can add field level validation where we actually tell the user that some fields were wrong, they can fill them. Or we can tell them that, no, there is something you did wrong, it's the server side error. We can block the input while we wait because we want to prevent them from editing the fields. We want to handle network issues. This is very important in case there is a lot of work done. And if they kind of lost the work, it will be bad for the user. We might save the values. If it's a model, we might want to consider while we're waiting for response, do we allow for leaving and lots of other things. We generally want to think about blocking versus non-blocking actions. Blockings are the actions that prevent you from leaving. Because your actions after this one depend on this one succeeding. There are also non-blocking actions, also called fire and forget. In those cases, we just want to display toasts when the action is complete. Always consider having a notification center or something where the user can look up the previously done actions. In general, we want to prevent double submissions. The simple solution is just to disable the action buttons.

8. Handling Idempotency and Context Loss#

Short description:

We want to use idempotency for important scenarios like booking or payments. Handling network issues involves retrying failed requests and informing the user through email or SMS. Idempotency allows safe retry of actions. Context loss occurs when navigating through the application, and we need to handle unmounting components and race conditions to prevent strange UI rendering.

Basically, we want to click it twice. However, that's not always good. If the page is refreshed, the button may be clicked again. The advanced solution is to use idempotency. We really want to use them for really important scenarios, such as booking or payments. They require additional work on the server side, but they will yield the best response for the user and for the UX.

Network issues, as mentioned earlier, we want to handle network issues in two different ways. There might be the outgoing issue, basically, we were unable to send the request to the server, thus failing, so they can retry again. Or actually, we send the request, however, while the server got the request, while the response was traveling back or while we were waiting, in the meantime, the network had some glitches. In that case, the server still processes our request, and the user can actually retry again and thus go into inconsistent state, basically doing the same action twice. We want to see if we can inform the user some other way, like using email notification center or SMS, that the action has been completed. As before, idempotency on the actions allows for safe retry, because you can actually send the same request twice, and the server will not do the same work twice. This requires idempotency, it cannot be done just by analyzing the request, because sometimes it's valid to do the same thing with the same data.

The context loss is the situation where we can navigate through the application, and then when the operation succeeds, something bad might happen. I have some links here you want to take into account when researching this topic. Let's take a look at a simple way of handling whether or not the component is mounted or not. This is a very simple hook that will tell you whether or not the component has been unmounted. We can use it in a very straightforward way by just basically checking if the component has been unmounted. This is a click handler. If we have useEffect, it becomes a little bit trickier because we can do it in three different ways. We can either split the work in the available part, and then make it cancelable, and then handle it in cache, basically separately. As you can see, the logic actually kind of gets split and this is not a really great solution. This can be done and we use the unsubscribed method to stop the asynchronous action. Another way is to use, again, isMounted the hook to know whether or not the component has been unmounted, basically return from the function import subsequent processing. The third way is to use something that's called cooperative cancellation, inspired by C-sharp. This code displays how one would actually create a token in the effect itself and then cancel it in the unsubscribed part. The asynchronous function after every await call must check if the cancellation is requested. Basically after await call, the component might be unmounted and we don't know so we have to check. Another thing we want to handle is the race conditions as shown in the demo. If we reuse the UI after actions, depending on the order of them arriving, this might render a very strange UI.

9. Considerations for Optimistic Updates#

Short description:

One final thing to consider is optimistic updates, where we pretend that an action succeeded immediately to make the UI responsive. However, this can lead to inconsistencies if subsequent actions encounter errors. In such cases, consider CRDT or other technologies for collaborative applications.

One final thing before I wrap this up is the optimistic updates. It's very common these days to have a client side caching and basically when initiating an action we actually pretend that the action succeeded immediately so that the UI looks very responsive and then later on we basically synchronize with the server. Please be advised that this might lead into very bad situations if there are subsequent actions that the user takes, because if there are network or any kind of other errors. If you don't handle it correctly in the UI, it can get pretty inconsistent pretty quickly. In that case, consider CRDT or other technologies if you're building for example collaborative applications.

Toni Petrina
Toni Petrina
21 min
25 Oct, 2021

Comments

Sign in or register to post your comment.
Available in other languages:

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Don't Solve Problems, Eliminate Them
React Advanced 2021React Advanced 2021
39 min
Don't Solve Problems, Eliminate Them
Top Content
Kent C. Dodds discusses the concept of problem elimination rather than just problem-solving. He introduces the idea of a problem tree and the importance of avoiding creating solutions prematurely. Kent uses examples like Tesla's electric engine and Remix framework to illustrate the benefits of problem elimination. He emphasizes the value of trade-offs and taking the easier path, as well as the need to constantly re-evaluate and change approaches to eliminate problems.
Jotai Atoms Are Just Functions
React Day Berlin 2022React Day Berlin 2022
22 min
Jotai Atoms Are Just Functions
Top Content
State management in React is a highly discussed topic with many libraries and solutions. Jotai is a new library based on atoms, which represent pieces of state. Atoms in Jotai are used to define state without holding values and can be used for global, semi-global, or local states. Jotai atoms are reusable definitions that are independent from React and can be used without React in an experimental library called Jotajsx.
Debugging JS
React Summit 2023React Summit 2023
24 min
Debugging JS
Top Content
Watch video: Debugging JS
Debugging JavaScript is a crucial skill that is often overlooked in the industry. It is important to understand the problem, reproduce the issue, and identify the root cause. Having a variety of debugging tools and techniques, such as console methods and graphical debuggers, is beneficial. Replay is a time-traveling debugger for JavaScript that allows users to record and inspect bugs. It works with Redux, plain React, and even minified code with the help of source maps.
The Epic Stack
React Summit US 2023React Summit US 2023
21 min
The Epic Stack
Top Content
Watch video: The Epic Stack
This Talk introduces the Epic Stack, a project starter and reference for modern web development. It emphasizes that the choice of tools is not as important as we think and that any tool can be fine. The Epic Stack aims to provide a limited set of services and common use cases, with a focus on adaptability and ease of swapping out tools. It incorporates technologies like Remix, React, Fly to I.O, Grafana, and Sentry. The Epic Web Dev offers free materials and workshops to gain a solid understanding of the Epic Stack.
Fighting Technical Debt With Continuous Refactoring
React Day Berlin 2022React Day Berlin 2022
29 min
Fighting Technical Debt With Continuous Refactoring
Top Content
Watch video: Fighting Technical Debt With Continuous Refactoring
This Talk discusses the importance of refactoring in software development and engineering. It introduces a framework called the three pillars of refactoring: practices, inventory, and process. The Talk emphasizes the need for clear practices, understanding of technical debt, and a well-defined process for successful refactoring. It also highlights the importance of visibility, reward, and resilience in the refactoring process. The Talk concludes by discussing the role of ownership, management, and prioritization in managing technical debt and refactoring efforts.
AHA Programming
React Summit Remote Edition 2020React Summit Remote Edition 2020
32 min
AHA Programming
Top Content
The Talk discusses the concept of AHA programming, which emphasizes thoughtful abstractions. It presents a live-coded example of the life-cycle of an abstraction and demonstrates how to fix bugs and enhance abstractions. The importance of avoiding complex abstractions and the value of duplication over the wrong abstraction are highlighted. The Talk also provides insights on building the right abstractions and offers resources for further learning.

Workshops on related topic

React, TypeScript, and TDD
React Advanced 2021React Advanced 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
Paul Everitt
Paul Everitt
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
Web3 Workshop - Building Your First Dapp
React Advanced 2021React Advanced 2021
145 min
Web3 Workshop - Building Your First Dapp
Top Content
Featured WorkshopFree
Nader Dabit
Nader Dabit
In this workshop, you'll learn how to build your first full stack dapp on the Ethereum blockchain, reading and writing data to the network, and connecting a front end application to the contract you've deployed. By the end of the workshop, you'll understand how to set up a full stack development environment, run a local node, and interact with any smart contract using React, HardHat, and Ethers.js.
Remix Fundamentals
React Summit 2022React Summit 2022
136 min
Remix Fundamentals
Top Content
Featured WorkshopFree
Kent C. Dodds
Kent C. Dodds
Building modern web applications is riddled with complexity And that's only if you bother to deal with the problems
Tired of wiring up onSubmit to backend APIs and making sure your client-side cache stays up-to-date? Wouldn't it be cool to be able to use the global nature of CSS to your benefit, rather than find tools or conventions to avoid or work around it? And how would you like nested layouts with intelligent and performance optimized data management that just works™?
Remix solves some of these problems, and completely eliminates the rest. You don't even have to think about server cache management or global CSS namespace clashes. It's not that Remix has APIs to avoid these problems, they simply don't exist when you're using Remix. Oh, and you don't need that huge complex graphql client when you're using Remix. They've got you covered. Ready to build faster apps faster?
At the end of this workshop, you'll know how to:- Create Remix Routes- Style Remix applications- Load data in Remix loaders- Mutate data with forms and actions
Vue3: Modern Frontend App Development
Vue.js London Live 2021Vue.js London Live 2021
169 min
Vue3: Modern Frontend App Development
Top Content
Featured WorkshopFree
Mikhail Kuznetsov
Mikhail Kuznetsov
The Vue3 has been released in mid-2020. Besides many improvements and optimizations, the main feature of Vue3 brings is the Composition API – a new way to write and reuse reactive code. Let's learn more about how to use Composition API efficiently.

Besides core Vue3 features we'll explain examples of how to use popular libraries with Vue3.

Table of contents:
- Introduction to Vue3
- Composition API
- Core libraries
- Vue3 ecosystem

Prerequisites:
IDE of choice (Inellij or VSC) installed
Nodejs + NPM
Developing Dynamic Blogs with SvelteKit & Storyblok: A Hands-on Workshop
JSNation 2023JSNation 2023
174 min
Developing Dynamic Blogs with SvelteKit & Storyblok: A Hands-on Workshop
Top Content
Featured WorkshopFree
Alba Silvente Fuentes
Roberto Butti
2 authors
This SvelteKit workshop explores the integration of 3rd party services, such as Storyblok, in a SvelteKit project. Participants will learn how to create a SvelteKit project, leverage Svelte components, and connect to external APIs. The workshop covers important concepts including SSR, CSR, static site generation, and deploying the application using adapters. By the end of the workshop, attendees will have a solid understanding of building SvelteKit applications with API integrations and be prepared for deployment.
Build Modern Applications Using GraphQL and Javascript
Node Congress 2024Node Congress 2024
152 min
Build Modern Applications Using GraphQL and Javascript
Featured Workshop
Emanuel Scirlet
Miguel Henriques
2 authors
Come and learn how you can supercharge your modern and secure applications using GraphQL and Javascript. In this workshop we will build a GraphQL API and we will demonstrate the benefits of the query language for APIs and what use cases that are fit for it. Basic Javascript knowledge required.