Astro avoids shipping any JavaScript to the client by default. However, there are occasions when client-side JavaScript is necessary. While Vanilla JS remains a viable option, frameworks are often preferred for their ability to address various challenges and streamline development processes, offering faster solutions for more complex use cases. Qwik takes an interesting approach to this, and boasts some interesting benefits. Let’s explore!
#Qwik? Resumability?
Qwik is the first framework that has similar DX (Developer Experience) as React, Vue, or Svelte in how you author components, while delivering Live HTML that is instantly interactive. Qwik achieves this property by completely removing the need for hydration. Instead, Qwik applications immediately execute the event handlers on user interaction, without having to bootstrap all the app state. This technique is called Resumability. — Qwik
#TL;DR
Within this guide, you’ll discover how to develop an Astro site leveraging Qwik’s Astro integration for client-side JavaScript functionality, as well as the process for deploying to Netlify. We’ll also explore some of the mechanics available and start building Qwik components.
#An example site
You can see a preview of the deployed site and the repository for the code on the following links.
- Preview: https://example-astro-qwik.netlify.app/
- Repository: https://github.com/netlify/example-astro-qwik/
Just deploy and play
#Getting started with Astro
To get started with Astro run the following:
If you prefer you can install Astro manually.
With an Astro site created you can commit the changes, push to your remote repository and deploy to Netlify.
#Deploy with Netlify
Creating a new Astro site on Netlify is simple. Once you’ve logged in, you’ll be taken to https://app.netlify.com. Click “Add new site” to add a new site, follow the on-screen steps and all the default settings will be completed for you.
For more information about deploying, you can read our Get Started with Netlify guide.
#Install the Qwik Astro integration
To install the integration run the following, then follow the instructions in your terminal.
The repository README contains more detailed installation information.
After a successful install you should see the following changes have been made to your astro.config.mjs
.
If you’re using TypeScript with Astro be sure to also update your tsconfig.json
with the following.
#Creating your first Qwik component
In the following code snippet you’ll create a button that, when clicked, will call a function that updates a counter value stored using Qwik’s useSignal Hook.
When signal values are updated, the component will re-render and the updated value will be displayed.
#Import and display
Qwik builds on top of Astro’s Zero JS, by default principle and then some. Thanks to resumability, the components are not executed unless resumed. Even with interactivity, the framework is also not executed until it needs to be. It is O(1) constant, … with zero effort on the developer. — Adding Qwik
As such, Qwik components don’t require Astro’s Client Directives. To see your new component import and return it in an Astro page.
#Your first Qwik component explained
If you’re new to Qwik there are a few things to understand.
#component$
All Qwik components are wrapped with component$
. This allows Qwik’s optimizer to break them down and lazy-load them.
You can read more about components in the Qwik docs.
#useSignal()
To update a signal, you apply changes directly to the .value.
In the above example you are updating the value of the counter
variable by using counter.value++
.
You can read more about useSignal
in the Qwik docs.
#Event handlers $
Similar to the component declaration, event handlers are also wrapped with a variation of the $
syntax. Eg. $(...)
.
You can read more about reusing event handlers in the Qwik docs.
#Event$
Qwik events are broadly the same as native JavaScript events, e.g onclick, but all will require
the trailing $
syntax. E.g onClick$
.
There are however some notable exceptions, for example onchange is onInput$
.
You can read more about events in the Qwik docs.
#Beyond the basics
The above example demonstrates a simple use of Qwik to define and manage client-side state, but Qwik can do so much more. Below you’ll find some examples of common requirements.
#useStore()
useStore()
is similar to useSignal()
but is used when the state values are more complex than a single primitive. In the following code snippet you’ll create a component that contains an HTML select element that updates a store value, and a modified version of the counter, but this time instead of incrementing a number, you’ll push a new Rocket emoji to an array.
Unlike useSignal
, with useStore
you update the value directly, rather than accessing the value using .value
.
In this example the handleRocket
function uses .push()
to add a new Rocket emoji to the store value named rockets
, which is typed as an array of strings.
The handleAstronaut
function sets the store value named astronaut
to equal that of the currentTarget.value
.
You can read more about useStore in the Qwik docs.
A note on currentTarget
Qwik requires the use of an additional argument to access the currentTarget.value
. Since event handling is asynchronous. The more common practice of using event.target.value
can’t be used with Qwik.
#useVisibleTask()
useVisibleTask()
is one of Qwik’s built-in methods and is only invoked when a component is within the viewport. If a component is not within the viewport Qwik won’t attempt to perform any actions contained within the function body. This can be helpful for client-side fetch requests where you don’t want to fetch data for UI elements the user can’t see.
In this example useVisibleTask
is used to make a fetch request to the GitHub API and retrieve some data. If the request is successful the store values are updated with data from the response.
In the return statement, a loading message is displayed if the value of store.html_url
is null.
You can read more about useVisibleTask
in the Qwik docs.
#Server-side rendering
To enable server-side rendering in Astro you can use the Astro Netlify Adapter. There is also an option to use Netlify Edge Functions which you can see in the docs here: Running Astro middleware on Netlify Edge Functions.
After a successful installation you will need to make following changes to your astro.config.mjs
.
#useTask()
With the Netlify adapter installed you can now use Qwik’s useTask
to make server-side requests. However, Astro can also be used to make server-side data requests.
The below code is broadly the same as the useVisibleTask
example, but the loading message has been removed since this data is requested and rendered on the server.
#You did it!
These are just a few examples of what you can achieve using Qwik. If you’re looking to continue your journey, why not explore the examples of state and tasks in the Qwik docs.