- Boil water for tea
- Steep matcha 90s
- Whisk into oat milk
Shared Props
When two or more islands share the same props (as serialized by devalue), the props are deduplicated to avoid shipping the same payload two or more times in one page load.
Each group below renders the same component three times with the same props. In the SSR: you'll find three <script type="application/json"> blocks (one per group) and nine <mochi-hydratable-island props-ref="…"> tags pointing at them. Each shared block carries a data-shared marker; a lone
island (like the source code viewer on this page) still gets its own block, just without that marker.
Group A — recipes
- Boil water for tea
- Steep matcha 90s
- Whisk into oat milk
- Boil water for tea
- Steep matcha 90s
- Whisk into oat milk
Group B — TODOs
- Reply to design review
- Bump devalue to 5.x
- Triage prop-dedup PR
- Push staging deploy
- Reply to design review
- Bump devalue to 5.x
- Triage prop-dedup PR
- Push staging deploy
- Reply to design review
- Bump devalue to 5.x
- Triage prop-dedup PR
- Push staging deploy
Group C — track
- Distance: 5.4 km
- Pace: 5:42 / km
- HR avg: 152 bpm
- Distance: 5.4 km
- Pace: 5:42 / km
- HR avg: 152 bpm
- Distance: 5.4 km
- Pace: 5:42 / km
- HR avg: 152 bpm
<script lang="ts">
import SharedPropsCard from './SharedPropsCard.svelte';
// Each payload is reused across three cards so Mochi dedupes it into one hoisted `<script type="application/json">` block instead of shipping it three times.
const groups = [
{
heading: 'Group A — recipes',
props: {
label: '<SharedPropsCard /> · A',
theme: { bg: '#1d2a23', fg: '#e6f1ea', accent: '#7fc89a' },
items: [
{ id: 1, text: 'Boil water for tea' },
{ id: 2, text: 'Steep matcha 90s' },
{ id: 3, text: 'Whisk into oat milk' },
],
},
},
{
heading: 'Group B — TODOs',
props: {
label: '<SharedPropsCard /> · B',
theme: { bg: '#26221d', fg: '#f1ece3', accent: '#d8a55c' },
items: [
{ id: 1, text: 'Reply to design review' },
{ id: 2, text: 'Bump devalue to 5.x' },
{ id: 3, text: 'Triage prop-dedup PR' },
{ id: 4, text: 'Push staging deploy' },
],
},
},
{
heading: 'Group C — track',
props: {
label: '<SharedPropsCard /> · C',
theme: { bg: '#1f242c', fg: '#e6ecf5', accent: '#7fa8d8' },
items: [
{ id: 1, text: 'Distance: 5.4 km' },
{ id: 2, text: 'Pace: 5:42 / km' },
{ id: 3, text: 'HR avg: 152 bpm' },
],
},
},
];
</script>
<p class="hint">
Each group below renders the same component three times with the same props. In the SSR: you'll find <strong>three</strong>
<code><script type="application/json"></code>
blocks (one per group) and nine <code><mochi-hydratable-island props-ref="…"></code> tags pointing at them. Each shared block carries a <code>data-shared</code> marker; a lone
island (like the source code viewer on this page) still gets its own block, just without that marker.
</p>
{#each groups as group (group.heading)}
<section class="group">
<h3>{group.heading}</h3>
<div class="row">
<SharedPropsCard mochi:hydrate {...group.props} />
<SharedPropsCard mochi:hydrate {...group.props} />
<SharedPropsCard mochi:hydrate {...group.props} />
</div>
</section>
{/each}
Styles
<style>
.hint {
margin: 0 0 1.5rem;
color: var(--text-muted);
font-size: 0.95rem;
line-height: 1.55;
}
.hint code {
font-family: var(--font-mono);
background: var(--surface-muted);
border: 1px solid var(--border);
padding: 0.05em 0.3em;
border-radius: 4px;
font-size: 0.85em;
}
.group {
margin-bottom: 2rem;
display: flex;
flex-direction: column;
gap: 0.6rem;
}
.group h3 {
margin: 0;
font-family: var(--font-serif);
font-size: 1.05rem;
font-weight: 500;
color: var(--text);
}
.row {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 0.75rem;
}
@media (max-width: 640px) {
.row {
grid-template-columns: 1fr;
}
}
</style>
More demos
isHydratable() How isHydratable() works — detect from any depth whether the current subtree will hydrate, for SSR-only fallbacks without prop forwarding. Cookies How cookies work — read and write on the server and the client through one MochiCookieJar API (cookies.get/set/delete). View Transitions How view transitions work — drop <ViewTransitions /> into a layout to animate full-page navigations with zero JavaScript.