Page updated Mar 6, 2024

Component slots

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 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.

  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

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) within your component.

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

  1. 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.

  2. 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

Want to undo your component slot creation?


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

Using a component slot

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
1/*Import your component*/
2import { Ampligram } from './ui-components';
3
4function App() {
5 return (
6 /*Add your component below*/
7 <Ampligram />
8 );
9}
10export 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

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.

1import { Ampligram } from '.ui-components';
2
3function App() {
4 return (
5 <Ampligram
6 style={styles.post}
7 comments={
8 //Pass your content into the component slot
9 <div>
10 <h1>Hi mom!</h1>
11 <p>Thanks for checking out my app</p>
12 </div>
13 }
14 />
15 );
16}
17export default App;

Here's how the code above would render in your app.

Screenshot of a component with static text in the component slot

Adding component slots to collections

Any component can be bound to data and used to generate to a collection, including components with component slots. Studio supports data binding to any GraphQL API created with Amplify, with and without DataStore.

Limitation: Nested data fetching for many-to-many relationships

Automatic nested data fetching for many-to-many relationships is currently not supported. Component slots only automatically fetch data for has One and has Many relationships, like one Post to many Comments.

Here, the Ampligram collection is mapped to a data model called Post. The Post model has a one-to-many relationship with the Comment model, so each Post can have many Comments. The AmpligramCollection below will render an Ampligram for each record in the Post model. Then, each related Comment will render in the comments component slot.

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

1import { AmpligramCollection } from './ui-components';
2
3function App() {
4 return (
5 <AmpligramCollection
6 overrideItems={({ item }) => ({
7 //Populate the "comments" slot
8 comments: (
9 <div>
10 {/*Map each related comment into a div*/}
11 {item.Comments.map((comment) => (
12 <div>{comment.content}</div>
13 ))}
14 </div>
15 )
16 })}
17 />
18 );
19}
20export default App;

Screenshot of component with dynamic content in the component slot

Dynamically rendering child components is where component slots get very useful - you can even pass another collection into this component slot.