---
title: Data Fetching
description: Fetch data on the server during pre-rendering and sync data to the client.
---

---

<Info>
This page is only relevant when using **static** or **server** mode.
</Info>

When pre-rendering your website on the server using either static or server mode, it is common to load some data for
example from a database or external api in oder to render out the content of your site. Loading data like this is usually
asynchronously and using server-side only apis like `dart:io`. Therefore:

1. You need to **delay the pre-rendering** of your site until all needed data is loaded.
2. Correctly **handle server-side logic** without breaking client-side compilation.
3. Make sure the loaded data is also **available on the client** for further client-side rendering.

---

Say you are developing a blog and want to show a list of articles on the website. Your articles are stored in some database
or CMS, and you also want the user to be able to filter the list on the client. This requires the following
data-loading strategy:

1. Asynchronously load the list of articles on the server during pre-rendering.
2. Pre-render the list of articles to the initial html of the website.
3. Additionally send the full list of articles as data to the client.
4. Hydrate the website on the client to enable interactivity.
5. When the user wants to filter the articles use the received article data to update the website content on the client.

---

With Jaspr loading data like this on the server and also syncing it with the client is build into the core framework,
and you have a couple of options to choose from.

## Loading data on the server

The main challenge when loading data on the server is to delay the pre-rendering until all data is loaded. Otherwise,
it wouldn't be part of the initial html of the website.

Jaspr has two main concepts that solve this:

### Asynchronous Components

Jaspr provides two special components that effectively have an asynchronous build method. This allows you to do
any asynchronous work during build, and also delay the build until the work is completed.

These components can only be used on the server and are only available using the
`package:jaspr/server.dart` import.

One of these, the `AsyncBuilder` component, can be used like this:

```dart
yield AsyncBuilder(builder: (context) async* {
  // Simply use "await" inside the build method.
  var data = await loadDataFromDatabase();

  // Renders the component after the data has loaded.
  yield MyOtherComponent(data: data);
});
```

Here you directly use `await` inside the build method. This may feel very strange or dangerous as a Flutter developer.
Be assured that this is perfectly safe, mainly for the reason that this component is **only executed on the server** and
**only built once** during pre-rendering. Therefore, you don't need to worry about potentially expensive rebuilds or floating async
operations with these components.

The other async component is the `AsyncStatelessComponent`, a variant of the `StatelessComponent` but with an async build method:

```dart
class MyAsyncComponent extends AsyncStatelessComponent {

  @override
  Stream<Component> build(BuildContext context) async* {
    // Simply use "await" inside the build method.
    var data = await loadDataFromDatabase();

    // Renders the component after the data has loaded.
    yield MyOtherComponent(data: data);
  }
}
```

Learn more about how to use the [AsyncBuilder](/components/async_components) and [AsyncStatelessComponent](/components/async_components).

### Preloading state of a StatefulComponent

If you have a `StatefulComponent` you can also load asynchronous data using the `PreloadStateMixin`:

```dart
class MyStatefulComponent extends StatefulComponent { /* ... */ }

class MyState extends State<MyStatefulComponent> with PreloadStateMixin {

  @override
  Future<void> preloadState() async {
    /* ... */
  }
}
```

The `preloadState()` method will only be executed on the server and will be called before `initState()`. It will defer
`initState()` as well as building the component until the future returned by the method is completed.

Learn more about how to use the [PreloadStateMixin](/utils/preload_state_mixin).

---

## Syncing data to the client

If you want to have an interactive website it's often not enough to only pre-render the website with the loaded data.
The used data also needs to be available on the client in order to update the data and re-render the website on user
interactions.

Therefore, it's often needed to also synchronize the data that's loaded on the server with the client. Jaspr has this
built into the framework in a couple of ways.

<Info>
The synchronization of data in Jaspr is only one-directional (from the server to the client) and is only performed
once for the initial rendering of the website. If you need to send data from the client to the server, or need a more
continuous loading of data, you should use a normal server-side api or realtime communication system like websockets.
</Info>

### Passing data through @client components

`@client` components are special annotated components that are automatically hydrated on the client to make your website
interactive. In addition to being a way to hydrate you website, they can also be used to pass data from the server to
the client.

When using such a component, all parameters of the component are serialized and sent to the client. When the component
is first built during hydration, it receives all the same parameters on the client that have been previously used on
the server during pre-rendering.

```dart
@client
class App extends StatelessComponent {
  // When this component is hydrated on the client, all parameters are passed
  // the same values as have been used during pre-rendering on the server.
  const App({required this.title, super.key});

  final String title;

  /* ... */
}
```

Read more about [@client](/utils/at_client) components and how they can be used to [sync data](/utils/at_client#passing-data)
from the server to the client.

### Using @sync on fields on a StatefulComponents

Alternatively, you can use the `@sync` annotation on any field of a `StatefulComponent`s `State` class which will
cause that field to be synced to the client and have the same value on the client as during pre-rendering on the server.

```dart
class MyComponent extends StatefulComponent { /* ... */ }

class MyComponentState extends State<MyComponent> {

  // This field will automatically sync its value from the server to the client.
  @sync
  int myValue = 0;

}
```

Read more about the [@sync](/utils/at_sync) annotation and how it syncs any field from the server to the client.

Additionally check out the [SyncStateMixin](/utils/sync_state_mixin) which is used internally by the `@sync` annotation
and can also be used directly to sync state of a `StatefulComponent` in a more flexible and explicit way.
