---
title: "Working with placeholders in a JSS React sample app"
slug: "working-with-placeholders-in-a-jss-react-sample-app"
abstract: "Placeholder techniques for React JSS applications"
---
# Working with placeholders in a JSS React sample app

There are several ways to use placeholders in a JSS React app.

> [!tip]
> We recommend you read our guide for [placeholders in JSS apps](https://doc.sitecore.com/xp/en/developers/hd/23/sitecore-headless-development/introducing-placeholders-in-jss-apps.html "Introducing placeholders in JSS apps") to understand what placeholders are and how they work.

<details>
<summary><h2>Basic placeholder technique</h2></summary>

The most common way to add a placeholder to a component is to use the `Placeholder` component.

```javascript
import { Placeholder } from '@sitecore-jss/sitecore-jss-react';

const App = ({ rendering }) => (
  <div>
    <h1>My App</h1>
    <Placeholder name="jss-main" rendering={rendering} />
  </div>
);

```

For the `Placeholder` component:

- The `name` is the key to the placeholder you are exposing.
- The `rendering` can represent:
    - The current Sitecore-provided layout/route data.
    - If you are exposing a placeholder from within another component, parent component data.
- For apps based on JSS 22.7 and later, you can optionally pass the Boolean `disableSuspense` prop. Setting this to `{true}` disables rendering of the `Suspense` component within the error boundary, helping to prevent hydration errors.

</details>

<details>
<summary><h2>Higher-order component placeholder technique</h2></summary>

The higher-order component (HOC) pattern lets you get an array of the components in a placeholder injected as a property to the component that exposes the placeholder.

```csharp
import { withPlaceholder } from '@sitecore-jss/sitecore-jss-react';

const Tabs = ({ tabs }) => {
  return (
    <div>
      {tabs}
    </div>
  );
};

export default withPlaceholder('tabs')(Tabs);

```

When you emit the component array, the application renders the components where you emit them. The main advantage of this technique is that there is no wrapper component. If you use the `Placeholder` component, all child components render underneath it in the component tree. If you emit the placeholder with this technique, the placeholder has no wrapping component and renders inline. This approach is handy when you are using libraries based on a specific component hierarchy, as shown in the following example of `react-fullpage`:

```xml
<SectionsContainer>
  <Section color="#69D2E7">Page 1</Section>
  <Section color="#A7DBD8">Page 2</Section>
  <Section color="#E0E4CC">Page 3</Section>
</SectionsContainer>

```

In the preceding sample, it is expected that the component hierarchy is `SectionsContainer->Section`. If you want, you can add the `Section` components using a placeholder so that Sitecore could define them. If you do this using the `Placeholder` component, the hierarchy instead looks like `SectionsContainer -> Placeholder -> YourComponent -> Section`:

```xml
<SectionsContainer>
  <Placeholder name="jss-sections" rendering={rendering} />
</SectionsContainer>

```

With the HOC-based placeholder, you can solve this with either inline components or component transformation:

### Inline components

If the library does not prevent a single layer of component wrapping, you can place the child component into your rendering component. obtaining a component hierarchy such as `SectionsContainer -> YourComponent -> Section` :

```csharp
import { withPlaceholder } from '@sitecore-jss/sitecore-jss-react';

const ContainerComponent = ({ sectionsPlaceholder }) => {
  return <SectionsContainer>{sectionsPlaceholder}</SectionsContainer>;
};

// you can also alias the property for the placeholder when using the HOC - or pass an array of placeholders
export const ContainerSitecoreComponent = withPlaceholder({ placeholder: 'sections', prop: 'sectionsPlaceholder' })(ContainerComponent);

// the <Section> is in the child Sitecore component added to the placeholder
export const ChildSitecoreComponent = (props) => (
  <Section>
    <h1>Your JSS or other React components here</h1>
  </Section>
);

```

### Component transformation

If you want a completely flat component hierarchy such as `SectionsContainer -> Section` in this example, you can take advantage of the injected property being an array to transform the child components with a wrapper using the map function. The child Sitecore components can be completely unaware of the wrapping and render only their content for a clean separation of concerns when using this technique.

```csharp
const ContainerComponent = ({ sectionsPlaceholder }) => {
  return (
    <SectionsContainer>
      {sectionsPlaceholder.map((component, index) => {
        // this if is important, as it prevents breakage when using Sitecore Experience Editor
        if (component.props && component.props.type === 'text/sitecore') return component;

        // wraps _all_ child components in a <Section> component
        return <Section key={index}>{component}</Section>;
      })}
    </SectionsContainer>
  );
};

export const ContainerSitecoreComponent = withPlaceholder({ placeholder: 'sections', prop: 'sectionsPlaceholder' })(ContainerComponent);

```

</details>

<details>
<summary><h2>Render Props API</h2></summary>

JSS supports the render props pattern if you prefer it to higher-order components. Using the `render` property of the `<Placeholder>` component, you can take over the rendering of placeholder contents the same way as with the higher-order component and use dynamic properties.

The following example illustrates how to get the components array and render it using render properties.

```javascript
import { Placeholder } from '@sitecore-jss/sitecore-jss-react';

const App = ({ rendering }) => (
  <div>
    <h1>My App</h1>
    <Placeholder name="jss-main" rendering={rendering} render={(components, placeholderData, props) => <div>{components}</div>} />
  </div>
);

```

You can use two optional arguments to the render function of the placeholder:

- The `props` parameter is a mirror of the properties passed to the `<Placeholder>`.
- The `placeholderData` parameter provides the current placeholder's layout data.

</details>

<details>
<summary><h2>Direct placeholder introspection</h2></summary>

If you want to access the data of a placeholder instead of its components, that is also possible. A good use case for this technique is components such as tabs that might need to render pieces in two places (the tab title and the tab contents). Because the placeholder hierarchy is a big JavaScript object, you can traverse it yourself using `props.rendering` to discover child component data and fields:

```csharp
const Tabs = ({ rendering, tabs }) => (
<Tab.Container>
  <div class="tabsHeading">
    {(rendering.placeholders.tabs || [])
      .filter((tab) => tab && tab.fields && tab.fields.title)
      .map((tab, index) => (
        <Tab.Heading key={index}>
          <Text field={tab.fields.title} />
        </Tab.Heading>
      ))}
  </div>

  <div class="tabContents">
    {tabs}
  </div>
</Tab.Container>
);

export default withPlaceholder('tabs')(Tabs);

```

Technically it is possible to take over and render a placeholder completely custom using this technique without using any placeholder component or HOC. We do not usually recommend this.

</details>

<details>
<summary><h2>Enhancing placeholders</h2></summary>

The `Placeholder` component supports several customizations that can enhance the developer experience. The same customizations are possible on the HOC placeholder by using the `propsTransformer` option to inject the same props using a function.

### Error components

If a rendering error occurs in a placeholder, the placeholder displays an error component instead of the placeholder contents and logs the error details to the console. You can customize this component by substituting your own React component using the `errorComponent` prop.

### Missing Component components

If a placeholder contains a rendering name that is unknown to the `componentFactory` (for example, a back-end developer creates a Foo rendering and adds it to a page, but there is no `Foo.js` yet), the rendering is replaced with a `MissingComponent` component defined in the `missingComponentComponent` property of your React component. The default implementation is a simple message, but you can customize it by using your own React component on the `missingComponentComponent` property.

### Handling hidden renderings

If personalization rules hide a rendering, the rendering is replaced by a `HiddenRendering` component to prevent error messages when the rendering is missing a JSS implementation. You can create a component and provide it to the placeholder using the `hiddenRenderingComponent` property.

</details>