export const meta = {
  title: `Component slots`,
  description: `Add component slots to Amplify-generated Figma to code components.  Use this to support nested components or collections in React code.`,
};

Component slots allow you to nest other components as React code within your Studio-generated UI components. You can use component slots to create dynamically generated child components, like Comments on a Post, or to replace a child element altogether.

## Adding a component slot
First, you'll need a component.
1. [Launch Studio](/console/adminui/start/#log-into-the-amplify-console) for an app.

2. On the left-hand navigation bar, click UI Library

3. Select a Figma component from your UI Library that you've imported into Studio.
*If you don't have any Figma components already, you can start with [Amplify's Figma UI file](/console/uibuilder/figmatocode/).*

4. Configure that component by clicking the **Configure** button in the upper right-hand corner.

![Animated image of opening a component and clicking the gear icon to configure](/images/console/slots-console1.gif)

Next, you'll add a component slot to this component.
1. On the left-hand side, you'll see the elements of your component. Select a Figma **Frame** (![Figma frame icon](/images/console/figma-frame-icon.png)) within your component.

  In this example, the "Area" frame is selected.

2. On the right-hand panel, click the "Convert to a slot" button. This will add a new prop to your UI component. Any JSX element you pass into that prop will be rendered in the generated component slot.

3. Optionally, change your property name.

  In this example, the property has been renamed "comments"

![Animated image of selecting a frame and add a component slot](/images/console/slots-console2.gif)

<Callout warning>

Want to undo your component slot creation?

Locate your component slot in the **Component properties** (top-right corner), click the triple-dot menu, and click **Erase property** to remove the component slot.

</Callout>

## Render the component with component slots in React code
### Importing your component
Once you've added a component slot to your component, click the **Get component code** button at the bottom of the screen to see instructions on the next steps.
1. Copy the `amplify pull` command, and run it in your Terminal
2. Copy the import code and paste it in your React app code
3. Lastly, render the component

```jsx
/*Import your component*/
import {
  Ampligram
} from './ui-components'

function App() {
  return (
    /*Add your component below*/
    <Ampligram  style={styles.post}/>
  );
}
const styles = {
  post: { width: 400, margin: '0 auto', padding: 20},
}
export default App;
```

Here's how the code above would render in your app. *Some minor styling has been added to help with visibility.*

![Screenshot of an imported component with a component slot](/images/console/slots1.png)

### Using your component slot to replace individual child components
To use the component slot, pass a child component as a property of the parent component, using the prop name you picked earlier. Then, the content you pass will be rendered as a child of the component.


````jsx
import {
  Ampligram
} from '.ui-components'

function App() {
  return (
    <Ampligram style={styles.post} comments={
      /* Pass your content into the component slot */
      <div style={styles.comment}>
        <h1>Hi mom!</h1>
        <p>Thanks for checking out my app</p>
      </div>
    }/>
  );
}
const styles = {
  post: { width: 400, margin: '0 auto', padding: 20},
  comment: { paddingLeft: 30, textAlign: 'left'},
}
export default App;
````

Here's how the code above would render in your app. *Some styling has been added to the comments to help with display.*

![Screenshot of a component with static text in the component slot](/images/console/slots2.png)

### Adding component slots to collections
Any component can be [converted to a collection](/console/uibuilder/collections/) and bound to data, and that includes components with component slots.  With a collection, you can [extend your component via code](/console/uibuilder/override/) using the `overrideItems` prop to generate unique content within each component slot.

Here, the Ampligram collection is mapped to a data model called Post. The Post model has a field called Comment, which contains an array of all the Comments associated with this Post. Each of these items in the Comment array is then mapped to the "comments" component slot you created.

Dynamically rendering child components is where component slots get very useful - you can even [pass another collection](/console/uibuilder/override/#nesting-collections) into this component slot.

<Callout note>

  <strong>Limitation: Nested data fetching for many-to-many relationships</strong>

Automatic nested data fetching for many-to-many relationships is currently not supported. Currently, component slots only automatically fetches data for [has One](/cli/graphql/data-modeling/#has-one-relationship) and [has Many relationships](/cli/graphql/data-modeling/#has-many-relationship), like one Post to many Comments.

</Callout>

The code below will render an Ampligram for each Post in the AmpligramCollection. Then, the Comments for each Post will render in the "comments" component slot.

In this example, the first Post has 2 comments, but the second post has none.

```jsx
import {
  AmpligramCollection
} from './ui-components'

function App() {
  return (
    <AmpligramCollection style={styles.post} overrideItems={({ item }) => ({
      comments:
      <div style={styles.post}>
        {item.Comments.map(comment => <div>{comment.content}</div>)}
      </div>
    })} />
  );
}
const styles = {
  post: { width: 400, margin: '0 auto', padding: 20},
  comment: { paddingLeft: 30, textAlign: 'left'},
}
export default App;
```

![Screenshot of component with dynamic content in the component slot](/images/console/slots3.png)
