provide
Provides a value under a context key in the active component and all its descendants.
Se autoimporta en las aplicaciones del framework.
import { provide } from "@meekojs/meeko";provide(key, value) stores value under key in the root of the component whose script is running. Any descendant (its children, their children, its snippet content and <MeekoTeleport> content) reads it with inject(key), which searches upward for the nearest provider. You can share something with a subtree without passing props at every level: a layout's theme, a compound component's state, a service.
It is exported from @meekojs/meeko and auto-imported in framework applications.
Usage#
<!-- app/layouts/default.meeko -->
<script lang="ts">
import { themeKey } from "../composables/theme";
const theme = signal<"light" | "dark">("light");
provide(themeKey, theme);
</script>
<template>
<div bind:class="theme.value"><MeekoOutlet /></div>
</template>All pages rendered by this layout can read inject(themeKey) and, because the value is a signal, react to its changes.
Type#
function provide<T>(key: ContextKey<T>, value: T): voidtype ContextKey<T> = symbol & {
readonly __meekoValue?: (value: T) => T
}Parameters#
| Parameter | Type | Default | Description |
|---|---|---|---|
key |
ContextKey<T> |
required | Key created with createContext. |
value |
T |
required | Value received by descendants' inject calls. For reactive reads, provide a signal or an object containing signals. |
Return value#
void. Without an active component or root, it throws Error: provide() requires an active component root.
Examples#
A service for a subtree#
// app/composables/cart.ts
import { createContext, inject, provide, signal, computed } from "@meekojs/meeko";
import type { ReadonlySignal } from "@meekojs/meeko";
interface Cart { readonly count: ReadonlySignal<number>; add(id: string): void }
const cartKey = createContext<Cart>("cart");
export function provideCart(): Cart {
const ids = signal<string[]>([]);
const cart: Cart = { count: computed(() => ids.value.length), add: (id) => { ids.value = [...ids.value, id]; } };
provide(cartKey, cart);
return cart;
}
export const useCart = (): Cart => inject(cartKey);Override a value in one branch#
A descendant can provide the same key again: its branch sees the new value and the rest of the tree sees the previous one.
<!-- app/components/DarkSection.meeko -->
<script lang="ts">
import { themeKey } from "../composables/theme";
const snippets = defineSnippets<{ default: [] }>();
provide(themeKey, signal<"light" | "dark">("dark"));
</script>
<template><section class="dark"><render snippet="snippets.default" /></section></template>Outside a component, in a custom root#
In a test or custom host, createRoot gives you a root in which to provide values:
import { createContext, createRoot, inject, provide } from "@meekojs/meeko";
const localeKey = createContext<string>("locale");
const value = createRoot(() => {
provide(localeKey, "es");
return createRoot(() => inject(localeKey)); // a child root finds it
});
// value === "es"Common mistakes#
Call it outside a component's script#
// app/utils/setup.ts, evaluated on import
provide(localeKey, "es");Throws Error: provide() requires an active component root. Provide from a component's script (for the entire application, app/app.meeko) or inside a composable called by that script:
<!-- app/app.meeko -->
<script lang="ts">
provide(localeKey, "es");
</script>Expect a sibling to read it#
provide only reaches descendants of the component that calls it.
<Sidebar /> <!-- llama a provide(panelKey, …) -->
<Content /> <!-- llama a inject(panelKey) --><Content> throws Error: Missing Meeko context: panel. Provide in the common ancestor:
<!-- the component containing both calls provide(panelKey, …) -->
<Sidebar />
<Content />Provide a fixed value that should change#
const theme = signal("light");
provide(themeKey, theme.value);Descendants receive the text "light" and do not learn about changes (it is also a type error if the key is for a Signal). Provide the signal:
provide(themeKey, theme);Notes#
- Server and browser. Works in both. In SSR, the value lives in that request's component root: two requests never share provided values.
- Where to call it. At the top level of the script, before rendering children: descendants look up the value when their own script runs.
- Not transferred. Provided values are not part of the payload state. The browser runs
provideagain during hydration; if the value must match the server's, it comes from props, route data or state signals. - Independent roots. Two unrelated roots (two applications mounted on the same page, or two non-nested
createRootcalls) do not share values. - Errors.
provideErrorHandleruses the same mechanism: an error observer provided in a component applies to its entire branch.