withastro / docs

Astro documentation
https://docs.astro.build/
MIT License
1.22k stars 1.3k forks source link

Using nanostores in astro components #7936

Open lstephensca opened 2 weeks ago

lstephensca commented 2 weeks ago

πŸ“š Subject area/topic

Nanostores

πŸ“‹ Page(s) affected (or suggested, for new content)

https://docs.astro.build/en/recipes/sharing-state-islands/ https://docs.astro.build/en/recipes/sharing-state/

πŸ“‹ Description of content that is out-of-date or incorrect

Currently, the docs pertaining to sharing-state-islands seem to advise against using nanostores in .astro components in the FAQ section. However, the docs for sharing-state demonstrates setting up nanostores for use inside .astro components with setting state/subscribing to changes. There appears to be a contradiction between the two.

πŸ–₯️ Reproduction in StackBlitz (if reporting incorrect content or code samples)

No response

Fryuni commented 2 weeks ago

I think that would benefit from some rewording, but they are not exactly contradicting.

Explaining:

Can I use Nano Stores in .astro files or other server-side components?

Nano Stores can be imported, written to, and read from in server-side components, but we don’t recommend it! This is due to a few restrictions:

  • Writing to a store from a .astro file or non-hydrated component will not affect the value received by client-side components.
  • You cannot pass a Nano Store as a β€œprop” to client-side components.
  • You cannot subscribe to store changes from a .astro file, since Astro components do not re-render.

That is referring to server-side components, on Astro components that means the frontmatter:

---
// This runs on the server, not recommended
import {flag} from './stores.js';

const flagValue = flag.get();
---

A <script> block in an Astro component is a plain client-side script generated by the Astro component, it is never executed on the server-side even when pre-rendering. Using nanostores there is not a problem.

---
---
<script>
// This runs on the client, perfectly fine
import {flag} from './stores.js';

const flagValue = flag.get();
</script>
lstephensca commented 2 weeks ago

Good point! I should have clarified a bit more in my issue regarding the differences between using nanostores in frontmatter and script blocks and not have been in a rush.

sarah11918 commented 2 days ago

Thanks for the conversation here! I wonder if something like this would address the issue?

Existing:

Nano Stores can be imported, written to, and read from in server-side components, but we don’t recommend it! This is due to a few restrictions:

Change to something like...

Nano Stores can be used in <script> tags to share state between .astro components. However, Using Nano Stores in the frontmatter of server-side components is not recommended because of the following restrictions:

Would something like that help? If so, would someone like to make a PR to update with clearer guidance?

Fryuni commented 1 day ago

I think that is a great improvement!