> Portal Navigation:
> 
> - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version.
> - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages).
> - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`).
> - Top-level index of all portals: https://dev.wix.com/docs/llms.txt
> - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt

## Resource: Component Integration Patterns

## Article: Component Integration Patterns

## Article Link: https://dev.wix.com/docs/studio-two/code-your-site/code-model/component-integration-patterns.md

## Article Content:

# Component Integration Patterns

A Studio Two component rarely works alone. Its manifest lets it expose state to other components, consume state another component exposes, and nest inside or wrap other components. Components can also call functions bundled into a function library.

Components work together through patterns including:

- [Connect an ERC to a Data Source](#connect-an-erc-to-a-data-source)
- [Shared Data Sources](#shared-data-sources)
- [Use a Wix context in an ERC's code](#use-a-wix-context-in-an-ercs-code)
- [ERC containers](#erc-containers)
- [ERC composed from ref elements](#erc-composed-from-ref-elements)
- [Function libraries](#function-libraries)

The manifest examples in this article show only the fields each pattern relies on. A full manifest also has fields such as `id`, `name`, and `resources`. The `type` of each component you build starts with the site's code identifier, which is always `companionApp` in a Studio Two site. The site's `wix.config.mjs` sets the identifier, and Studio Two rejects a manifest for your own component whose `type` doesn't start with `companionApp.`. A type that names one of Wix's built-in elements, such as `wix-basic-input` in a `refElement`, keeps the identifier Wix gave it.

## Connect an ERC to a Data Source

Editor binding creates a connection between a Data Source and an Editor React Component (ERC) through the Studio Two editor. Data Source is the Studio Two UI name for a context provider extension. Unlike direct React prop passing, the connection is configured by a Wix user and mediated by the context provider and ERC manifests.

Use this pattern when an ERC is generic enough that it shouldn't be tied to one specific context. A card component that displays a name, an image, and a description, for example, could bind to a team member context on one page and a product context on another. The Wix user decides which context feeds it, rather than the code assuming it in advance. To tie an ERC to one Wix business solution's context instead, see [Use a Wix context in an ERC's code](#use-a-wix-context-in-an-ercs-code).

### How it works

1. The context provider manifest for the Data Source declares what it exposes in `context.items`.
2. The ERC's manifest declares what it accepts in its `data` section.
3. In the editor, a Wix user connects a context item to an ERC prop.
4. Studio Two passes the bound value as a prop to the ERC at runtime.

The manifest for the team member Data Source exposes a name and a photo:

```ts
{
  type: "companionApp.teamMemberContext",
  context: {
    items: {
      name: { dataType: "text" },
      photo: { dataType: "image" }
    }
  }
}
```

The card ERC's manifest declares the props it accepts:

```ts
{
  type: "companionApp.card",
  data: {
    title: { dataType: "text" },
    image: { dataType: "image" }
  }
}
```

Once `name` is bound to `title` and `photo` to `image`, the card receives them as ordinary props:

```tsx
function Card({ title, image }: { title: string; image: Image }) {
  return (
    <div>
      <img src={image.url} alt={title} />
      <p>{title}</p>
    </div>
  );
}
```

The context item and the ERC prop don't need matching names, since the Wix user is the one who connects them.

The same binding surface also connects a function-typed prop to a function from a [function library](#function-libraries), not just to a Data Source.

## Shared Data Sources

The context provider behind a Data Source stores state that several ERCs can share. Each ERC connects to the same Data Source through editor binding, even when the ERCs are otherwise unrelated. The ERCs don't pass props to one another or import the provider. Each one receives the values and functions it's connected to as ordinary props.

Use this pattern when several ERCs need the same state, such as a count and the buttons that change it.

### How it works

1. The context provider manifest declares the shared values and functions in `context.items`.
2. Each ERC manifest declares only the prop that the ERC needs.
3. In the editor, a Wix user attaches the Data Source to a page, container, or section. Then they connect a prop of each ERC inside that area to a context item. For how to attach a Data Source, see [Connect to Source](https://support.wix.com/en/article/connect-to-source).
4. When the provider updates its state, every connected ERC that receives an updated value renders again.

Only ERCs nested inside that page, container, or section can connect to the Data Source.

The context provider manifest for a counter Data Source exposes a count and the functions that change it:

```ts
{
  type: "companionApp.counterContext",
  context: {
    items: {
      count: { dataType: "number", displayName: "Count" },
      increment: { dataType: "function", displayName: "Increment" },
      decrement: { dataType: "function", displayName: "Decrement" }
    }
  }
}
```

Three unrelated ERCs, a count display and two separate buttons, each declare just the prop they need:

```ts
{ type: "companionApp.countDisplay", data: { count: { dataType: "number" } } }

{ type: "companionApp.incrementButton", data: { increment: { dataType: "function" } } }

{ type: "companionApp.decrementButton", data: { decrement: { dataType: "function" } } }
```

Each ERC receives its connected value or function as a prop:

```tsx
function CountDisplay({ count }: { count: number }) {
  return <span>{count}</span>;
}

function IncrementButton({ increment }: { increment: () => void }) {
  return <button onClick={increment}>+</button>;
}

function DecrementButton({ decrement }: { decrement: () => void }) {
  return <button onClick={decrement}>-</button>;
}
```

In the editor, a Wix user connects the count display's `count` prop to the `count` item, and each button's function prop to the matching function.

When a site visitor clicks either button, the button calls its connected function, and the provider updates the count. The count display receives the new value and renders again.

## Use a Wix context in an ERC's code

Many Wix business solutions provide React contexts that hold the solution's data and functionality. An ERC can use a Wix business solution context directly by calling the context's React hook in its own code. For example, the Stores Product Context holds a product's details, prices, and stock, the site visitor's selected options, and functions such as adding the selection to the cart. A business solution provides its context on some of its own pages, through a Data Source a Wix user attaches, such as the **Product** Data Source, or for each item in one of its lists.

Use this pattern when an ERC is built for one business solution and should adapt to wherever a Wix user places it, without the Wix user connecting each prop. A price display that reads the Product Context, for example, shows the price of whichever product the surrounding page, Data Source, or list item provides.

### How it works

1. The ERC's code imports the context's hook from the business solution's package and calls it.
2. The ERC's manifest declares the context as a dependency in its `resources`.
3. A Wix user places the ERC inside a page, container, section, or list item that provides the context.
4. At runtime, the hook returns the context's current values and functions. When a value changes, such as the price after a site visitor selects an option, the ERC renders again.

A price display ERC reads the price and stock of the product its context provides:

```tsx
import { useProductContext } from '@wix/stores/context/product';

export default function ProductPrice({ id, className }: { id: string; className: string }) {
  const { pricing, isInStock } = useProductContext();

  return (
    <div id={id} className={`product-price ${className}`}>
      <span>{pricing.currentSellingPrice?.formattedAmount}</span>
      {!isInStock && <span>Out of stock</span>}
    </div>
  );
}
```

Each context's [reference](https://dev.wix.com/docs/contexts.md) lists the pages, Data Sources, and list items that provide it. Anywhere else, the context's hook throws an error.

In the editor, many Wix contexts fill empty values with sample content, so a Wix user designs with realistic data. Each context's reference describes its behavior in the editor.

### Choose between the hook and editor binding

Both patterns get values from a context or Data Source into an ERC. They differ in who decides the connection and what the ERC depends on:

| | Editor binding | The context's hook |
|---|---|---|
| Who chooses the source | The Wix user, in the editor | You, in the ERC's code |
| Where the ERC works | Anywhere, since it doesn't depend on a specific context | Only inside a page, Data Source, or list item that provides the context |
| What the ERC gets | Each item the Wix user connects, as a prop | Every property and function the context has |
| Which contexts | Any Data Source, Wix or custom | Wix business solution contexts |

For every Wix business solution context, its properties and functions, and where it's available, see [Wix Business Solution Contexts](https://dev.wix.com/docs/contexts.md). For the steps, see [Use a Wix Context in an Editor React Component in Studio Two](https://dev.wix.com/docs/studio-two/code-your-site/code-model/editor-react-components/use-a-wix-context-in-an-editor-react-component-in-studio-two.md).

## ERC containers

An ERC can declare container slots, where a Wix user drops other elements, including other ERCs, as children. The parent ERC receives what's in each slot as a prop and renders it, so components nest inside one another the way plain React components do.

Use this pattern when an ERC's job is to arrange other components rather than render all of its content itself. A collapsible section, for example, renders its own header and toggle, but it doesn't know or care what a Wix user puts in its body.

Two container types cover most ERCs:

- **Simple:** One fixed slot, such as the body of a collapsible section.
- **Template:** A slot that repeats once per item in an array, such as a card in a product grid. This is the mechanism behind a repeater.

### How it works

1. The parent ERC's manifest declares a data item with the container data type. Its `container` object sets `containerType`, and a `selector` that matches the element in the component that holds the slot.
2. In the Studio Two editor, a Wix user drops elements into the slot. Those children are saved with the page, not in your source files.
3. At runtime, Studio Two passes the slot's content to the parent ERC as the prop named after the data item. The ERC renders it inside the element that `selector` matches.

In a Studio Two site, the container belongs with your manifest overrides in `<component-folder>.extension.ts`, which regenerating the manifest doesn't overwrite. For how overrides work, see [Build an Editor React Component in Studio Two](https://dev.wix.com/docs/studio-two/code-your-site/code-model/editor-react-components/build-an-editor-react-component-in-studio-two.md).

Set the data type and the container type with the `DATA` and `CONTAINER_TYPE` enums from `@wix/react-component-schema`. A plain string such as `'simple'` fails type checking. Like every manifest selector, the slot's `selector` must match a plain string class, because CSS Modules rewrite module class names at build time.

### Simple containers

The collapsible section ERC declares one slot for its body:

```ts
import { CONTAINER_TYPE, DATA } from '@wix/react-component-schema';

// ...

editorElement: deepmerge(editorElementWithDefaults, {
  data: {
    content: {
      dataType: DATA.DATA_TYPE.container,
      displayName: 'Section content',
      container: {
        selector: '.section-content',
        containerType: CONTAINER_TYPE.simple,
      },
    },
  },
}),
```

The component types the prop as `Container` from `@wix/editor-react-types`. A container arrives as either a React node or a function, so the component renders a node and calls a function. The prop has no default, because its content comes from the editor. The component hides the body with `hidden` instead of removing it, so the element that `selector` matches is always rendered:

```tsx
import React, { useState } from 'react';
import type { Container } from '@wix/editor-react-types';

type CollapsibleSectionProps = {
  id: string;
  className?: string;
  title?: string;
  content?: Container;
};

export default function CollapsibleSection({
  id,
  className,
  title,
  content,
}: CollapsibleSectionProps) {
  const [open, setOpen] = useState(true);

  return (
    <section id={id} className={`collapsible-section ${className ?? ''}`}>
      <button type="button" onClick={() => setOpen(!open)}>
        {title}
      </button>
      <div className="section-content" hidden={!open}>
        {typeof content === 'function' ? content({}) : content}
      </div>
    </section>
  );
}
```

### Template containers

A template container points to an array data item. Instead of a single value, the parent ERC receives a render function and calls it once per item in the array. A product grid, for example, doesn't know in advance how many products a Wix user's catalog has, so it needs a slot that repeats to fit the array.

The product grid ERC declares a `products` array and a template container tied to it:

```ts
import { CONTAINER_TYPE, DATA } from '@wix/react-component-schema';

// ...

editorElement: deepmerge(editorElementWithDefaults, {
  data: {
    products: {
      dataType: DATA.DATA_TYPE.arrayItems,
      arrayItems: {
        data: {
          items: {
            name: { dataType: DATA.DATA_TYPE.text },
            price: { dataType: DATA.DATA_TYPE.number },
          },
        },
      },
    },
    renderProduct: {
      dataType: DATA.DATA_TYPE.container,
      displayName: 'Product',
      container: {
        selector: '.product-slot',
        containerType: CONTAINER_TYPE.template,
        template: { dataItemPath: { dataItemKey: 'products' } },
      },
    },
  },
}),
```

The component receives `renderProduct` as a function that takes an item and its index. It renders each result inside an element with the slot's class:

```tsx
import React from 'react';
import type { ReactNode } from 'react';

type Product = { name: string; price: number };

type ProductGridProps = {
  id: string;
  className?: string;
  products?: Product[];
  renderProduct?: (item: Product, index: number) => ReactNode;
};

export default function ProductGrid({
  id,
  className,
  products = [],
  renderProduct,
}: ProductGridProps) {
  return (
    <div id={id} className={`product-grid ${className ?? ''}`}>
      {products.map((product, index) => (
        <div key={index} className="product-slot">
          {renderProduct?.(product, index)}
        </div>
      ))}
    </div>
  );
}
```

For every container field, see [Container Data Types](https://dev.wix.com/docs/site-extensions/editor-react-components/editor-element/data/container-data-types.md) and [Container](https://dev.wix.com/docs/site-extensions/editor-react-components/editor-react-types/reference/container.md).

## ERC composed from ref elements

An ERC's manifest can use Wix's own built-in elements as part of its structure. A `refElement` in the manifest references an existing Wix element, like a button or an input, and inherits its behavior and definitions, which the developer can then override, for example to disable editing on a CSS property or change a display name.

Use this pattern when rebuilding a piece of UI from scratch would mean losing behavior that's worth keeping, like built-in validation or accessibility. A signup form ERC's email field, for example, is better off reusing Wix's input element than reimplementing email validation itself.

### How it works

1. The ERC's manifest adds a `refElement` entry referencing an existing Wix element.
2. That entry can override specific fields of the original element, like its display name or whether a property is editable.
3. Wix merges the overrides with the original element's definition, and the result appears in the editor and at runtime as part of the ERC.

The signup form ERC's manifest references Wix's input element for its email field, keeping its built-in validation locked in place:

```json
{
  "elementType": "refElement",
  "refElement": {
    "type": "wix-basic-input",
    "selector": ".emailInput",
    "displayName": "Email Field",
    "data": {
      "placeholder": { "displayName": "Placeholder Text" },
      "validation": { "disableEditing": true }
    }
  }
}
```

## Function libraries

An Editor Function Library bundles reusable, stateless functions that a Wix user can connect to a slot in the editor, the same way they'd connect a context-exposed function. Its manifest declares each function's parameters and return type, the same way a context declares its items.

Use this pattern for utilities that many otherwise-unrelated components need to share, like currency formatting or a shared validation rule, where the state and lifecycle of a Data Source would be unnecessary overhead.

### How it works

1. The function library's manifest declares each function's name, parameters, and return type.
2. The manifest's `resources.client` points to the bundle where those functions are implemented.
3. In the editor, a Wix user connects one of the library's functions to a slot, such as an ERC prop, using the same binding surface used to [connect a function exposed by a Data Source](#connect-an-erc-to-a-data-source).
4. The user connects each of the function's own parameters to its own source, such as a context item or a static value, the same way any other slot gets bound.
5. Studio Two calls the bound function and passes its result to the slot at runtime.

A library of string utilities declares its functions like this:

```json
{
  "type": "companionApp.stringUtilFunctions",
  "functions": {
    "capitalize": {
      "parameters": [{ "dataType": "text", "displayName": "Text to capitalize" }],
      "returns": { "dataType": "text" }
    }
  },
  "resources": {
    "client": { "url": "https://cdn.example.com/string-utils-bundle.js" }
  }
}
```

## See also

- [About Data Sources](https://dev.wix.com/docs/studio-two/code-your-site/code-model/data-sources/about-data-sources.md)
- [Build a Data Source in Studio Two](https://dev.wix.com/docs/studio-two/code-your-site/code-model/data-sources/build-a-data-source-in-studio-two.md)
- [Context Reference](https://dev.wix.com/docs/site-extensions/context-providers/context-reference.md): the `context` section of a context provider manifest
- [Wix Business Solution Contexts](https://dev.wix.com/docs/contexts.md)
- [Use a Wix Context in an Editor React Component in Studio Two](https://dev.wix.com/docs/studio-two/code-your-site/code-model/editor-react-components/use-a-wix-context-in-an-editor-react-component-in-studio-two.md)
- [About Function Libraries](https://dev.wix.com/docs/studio-two/code-your-site/code-model/function-libraries/about-function-libraries.md)
- [Function Reference](https://dev.wix.com/docs/site-extensions/function-libraries/function-reference.md)