Skip to content

feat: explain the limitations of serialization #10944

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
11 changes: 7 additions & 4 deletions src/content/docs/en/guides/framework-components.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,16 @@ import Counter from '../components/Counter.svelte';
</div>
```

:::caution[Passing functions as props]
You can pass a function as a prop to a framework component, but it only works during server rendering. If you try to use the function in a hydrated component (for example, as an event handler), an error will occur.

This is because functions can't be _serialized_ (transferred from the server to the client) by Astro.
:::


Props that are passed to interactive framework components [using a `client:*` directive](/en/reference/directives-reference/#client-directives) must be [serialized](https://developer.mozilla.org/en-US/docs/Glossary/Serialization): translated into a format suitable for transfer over a network, or storage. However, for performance and/or security reasons, Astro does not serialize every type of data structure. Therefore, there are some limitations on what can be passed as props to hydrated components.

The following prop types are supported:
`plain object`, `number`, `string`, `Array`, `Map`, `Set`, `RegExp`, `Date`, `BigInt`, `URL`, `Uint8Array`, `Uint16Array`, `Uint32Array`, and `Infinity`

Non-supported data structures passed to components, such as functions, can only be used during the component's server rendering and cannot be used to provide interactivity. For example, passing functions to hydrated components is not supported because Astro cannot pass functions from the server in a way that make them executable on the client.

## Passing children to framework components

Inside of an Astro component, you **can** pass children to framework components. Each framework has its own patterns for how to reference these children: React, Preact, and Solid all use a special prop named `children`, while Svelte and Vue use the `<slot />` element.
Expand Down
9 changes: 9 additions & 0 deletions src/content/docs/en/guides/server-islands.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ const avatarURL = await getUserAvatar(userSession);
---
<img alt="User avatar" src={avatarURL} />
```
:::caution[Server Island Prop Limitations]
You can pass a function as a prop to a server island component, but this only works during server rendering. If you try to use the function in a hydrated component (for example, as an event handler), an error will occur.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can pass a function as a prop to a server island component, but this only works during server rendering.

Server islands are always server rendered. That is their purpose, make something server rendered even on a statically pre-rendered page. So this seems a bit unhelpful.

Functions can be passed as props while on the server, they can't be passed to the components marked with server:defer. Meaning you can pass functions around on a server island, but never to a server island.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @Fryuni! Thanks again. I'll steal some of what you wrote here as it was very helpful for me to better understand the limitation, specifically this point: Meaning you can pass functions around on a server island, but never to a server island.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you try to use the function in a hydrated component (for example, as an event handler), an error will occur.

This example seems weird to me. Server islands are not hydrated (at least not in the sense we use anywhere else in the docs for that word, it doesn't add handlers and bindings for interactivity to existing DOM nodes). They get replaced with the content of a separate request when loaded.

The fallback/original content doesn't require any hydration and neither does the code after the swap. After the swap there isn't even any JS related to the server island in the document, contrary to hydration, which is also a win for server island, and might give people the idea that server islands are heavier on their site than it really is.


This is because functions cannot be _serialized_ (transferred from the server to the client) by Astro. Objects with circular references are also not serializable.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should have the same wording regarding serialization as the client islands. Even more so here to not say that the limitation is regarding sharing information with the client because that is an implementation detail. It could send the information between instances of the server (which might remove some other limitations we currently have) and it would have the same problem.


Props provided to hydrated components must be serializable. The following prop types are supported:
`plain object`, `number`, `string`, `Array`, `Map`, `Set`, `RegExp`, `Date`, `BigInt`, `URL`, `Uint8Array`, `Uint16Array`, `Uint32Array`, and `Infinity`
:::


## Server island fallback content

Expand Down