Subchapter 1.26
references/context-provider/PROVIDER_PATTERN.mdMarkdown4 KBView on GitHub
import React, { createContext, useContext, useState } from 'react';
import type { Text } from '@wix/editor-react-types';
// 1. Define the context type interface (use @wix/editor-react-types types, not plain primitives)
export interface MyContextType {
someValue: Text;
someAction: () => void;
}
// 2. Define the provider props interface (matches `data` in registration)
export interface MyProviderProps {
children?: React.ReactNode;
initialValue: Text;
}
// 3. Create the context (use null, not undefined)
const MyContext = createContext<MyContextType | null>(null);
MyContext.displayName = 'MyContext';
// 4. Export the hook
export function useMyContext(): MyContextType {
const context = useContext(MyContext);
if (!context) {
throw new Error('useMyContext must be used within a MyProvider');
}
return context;
}
// 5. Export the provider component (also as default)
export function MyContextProvider({
children,
initialValue,
}: MyProviderProps): React.ReactNode {
const [someValue, setSomeValue] = useState<Text>(initialValue || '');
const someAction = () => {
setSomeValue('updated');
};
const api: MyContextType = {
someValue,
someAction,
};
return (
<MyContext.Provider value={api}>{children}</MyContext.Provider>
);
}
MyContextProvider.displayName = 'MyContextProvider';
export default MyContextProvider;displayName for both the context and the provider component — for human readabilitycontextSpecifier.hook field references it by namedefault — the Wix runtime loads the context provider via its default exportnull. Keep it throwing when a consumer hits the error; fix the consumer’s placement instead (see When the Hook Throws)children as a prop — the provider wraps whatever the Editor places inside it (page, container, or section content) in the React tree@wix/editor-react-types (e.g., NumberType, Text, BooleanValue) instead of plain TypeScript primitives — these types match the actual runtime format Wix provides to components as props, so using plain primitives creates a type mismatchdata entries in the extension registrationdata prop into state the provider never changes — read it straight from props. A data prop is edited in the Editor panel, and useState(prop) keeps only the value it saw on mount, so the panel edit never reaches the page. Copy it into state only when the provider itself writes to that value, and name the prop for what it is (initialValue) so the seed-once behavior is intended rather than a surpriseRegardless of what the current request asks for:
contextSpecifier. A request phrased “use native elements, do not create an editor react component” constrains the consumers, never the provider’s shape. contextSpecifier.hook is a required manifest field — dropping the hook export or contextSpecifier breaks the manifest for every consumer.count stays for the text element that displays it; isCongratsBannerHidden is added for the element gated on it. Derived items are additive — they never replace the state they are derived from.Exposing an item costs nothing: a consumer can ignore any item it does not need.
A provider makes one binary decision for its whole subtree: while its initial data is unresolved, nothing inside it renders — including children bound to nothing at all. Awaiting a promise without handling this ships a blank page on load.
This applies to every promise — every Wix SDK call, every fetch, every await, however fast it usually resolves. A quick call is not an exemption: it still resolves after the first render, so the gate still closes. If producing any context value involves a promise, you MUST read LOADING.md and build the provider the way it describes.