---
title: Shared state
description: Share one piece of state between components with shared().
sidebar: { label: Shared }
---

A computed lives inside one component. Now a badge and a button, in two components, both need the same `count`.

Define the state once with `shared()`. Each component that calls the definition gets the same `count`. A change from one component shows up in the other.

Click **+1** in the figure.

<StateSharedFigure />

Notice that the click runs in Counter, but the number changes in Badge.

```tsrx Counter.tsrx
import { shared, state } from '@markless/core';

export const counter = shared(() => {
	const box = state({ count: 0 });
	return { ...box, increment() { box.count++; } };
}, { scope: 'page' });

function Badge() @{
	const c = counter();
	<output>{c.count}</output>
}

export default function Counter() @{
	const c = counter();
	<main><Badge /><button onClick={() => c.increment()}>+1</button></main>
}
```

The function inside `shared()` creates the state. It returns the state plus any methods, like `increment()`.

## Who shares it

The second argument picks the group that shares one copy.

| Scope | Who gets the same copy |
| --- | --- |
| `{ scope: 'page' }` | Every component on the page. This is the default. |
| `{ scope: 'widget' }` | One copy for each rendered widget, like each menu or each dialog. |

[UI components](/ui/overview) use `'widget'` so each menu keeps its own open or closed state.

:::tip[Why do I get a missing-scope warning?]
If two components in one file call the same definition with no scope, you get `MARKLESS_SHARED_FAMILY_SCOPE_IMPLICIT`. Write `{ scope: 'widget' }` for one copy per widget. Write `{ scope: 'page' }` to keep one copy for the page.
:::

:::warning[Sharing across files]
Keep the definition and the components that call its methods in one file, as the example does. From another file, a call like `c.increment()` can stop the build with `MARKLESS_SHARED_METHOD_CROSS_MODULE`. There, change the field directly: `c.count++`.
:::

Use `state()` when one component owns the value. Use `shared()` when several components need it.

**Next:** How does a click reach `increment()`? [Events →](/state/events)
