# Component hierarchy constraints

Understand the constraints that determine component rendering.

When writing your Stripe app, you can define your component tree in the way that best fits your needs using the `@stripe/ui-extension-sdk/ui` component library. Although we allow you to decide how to define your component tree, a few components have rules that govern how to use or compose them.

## Why hierarchy constraints exist

In some cases, components have relational constraints—either because they depend on an internal context, or because the underlying component expects them to compose a specific UI. Composing them outside of their expected hierarchy can result in a broken or unpredictable UI.

In other cases, we designed components as root layouts. For these, the SDK runs validations to catch unintended layout compositions early.

## Runtime validation

In *development mode*, hierarchy constraint violations give you an error and crash your application. The error helps you identify the issues and shows you how to fix it.

In *production mode*, you won’t get an error. Rendering proceeds normally, but results can vary. You could see a blank view or an incorrect layout.

## Types of validation

We have two types of validation: parent component and root component.

### Parent component validation

You must render some components inside a specific parent. For example, you must render `AccordionItem` inside an `Accordion`. Rendering it elsewhere gives you an error.

#### ❌ Incorrect usage

```jsx
import {AccordionItem, Box} from '@stripe/ui-extension-sdk/ui';

export default function MyComponent() {
  return (
    <Box>
      {/* ❌ AccordionItem must be inside an Accordion */}
      <AccordionItem title="Add business info">
        business info content
      </AccordionItem>
    </Box>
  );
}
```

```
Error in extension: <your-extension-id>
An error occurred while rendering the X view.
Invalid usage of AccordionItem component. It's currently nested within Box component. Allowed parents are: Accordion
```

#### ✅ Correct usage

```jsx
import {Accordion, AccordionItem} from '@stripe/ui-extension-sdk/ui';

export default function MyComponent() {
  return (
    <Accordion>
      {/* ✅ AccordionItem properly nested inside Accordion */}
      <AccordionItem title="Add business info">
        business info content
      </AccordionItem>
    </Accordion>
  );
}
```

### Root component validation

You can only use some components at the root level of your component tree. For example, `FullPageView` must be the root element. Rendering it as a child of any other component gives you an error.

> Root components are viewport-specific. You can only use `FullPageView` as the root component of the `stripe.dashboard.fullpage` viewport—you can’t use it as the root of any other view.

#### ❌ Incorrect usage

```jsx
import {FullPageView, Box, FocusView} from '@stripe/ui-extension-sdk/ui';
import { useState } from 'react';

export default function MyComponent() {
  const [shown, setShown] = useState(false);

  return (
    <FocusView title="My Focus View" shown={shown} setShown={setShown}>
      {/* ❌ FullPageView must be the root element */}
      <FullPageView>
        <Box>Hi</Box>
      </FullPageView>
    </FocusView>
  );
}
```

```
Error in extension: <your-extension-id>
An error occurred while rendering the X view.
Invalid usage of FullPageView component. It's currently nested within FocusView component. FullPageView component can only be used as the root element
```

#### ✅ Correct usage

```jsx
import {FullPageView, Box} from '@stripe/ui-extension-sdk/ui';

export default function MyComponent() {
  return (
    <FullPageView>
      {/* ✅ FullPageView is the root element */}
      <Box>Hi</Box>
    </FullPageView>
  );
}
```
