Understanding the Object Prop

I had a hard time understanding the object prop and why to use it, so I asked ChatGPT for an explanation. Now, I am thinking I am doing my cards completely wrong.

Object Props are one of Etch’s most useful tools for building dynamic, reusable components. They are especially helpful for cards, listings, and other components that need several values from the same post, event, product, person, or other structured data source.

The basic idea is simple:

An Object Prop passes a complete structured data object into a component.

Instead of passing a post’s title, image, excerpt, and URL through four separate props, you can pass the entire post object through one Object Prop. The component can then read the individual values it needs.

This article explains why Object Props exist, how their syntax works, and how to implement one in a reusable Post Card component. It is designed as a companion to the accompanying video, so you can follow the build onscreen and return here for the code and key concepts.

The mental model: hand the component a box

Think of an object as a box containing related information:

Post object
├── title
├── excerpt
├── featuredImage
├── permalink
├── author
└── date

If an Object Prop has the key post, the component receives that entire box as:

props.post

It can then open the box and retrieve individual values:

props.post.title
props.post.excerpt
props.post.permalink.relative

Each dot moves one level deeper into the supplied object.

Why Object Props are necessary

The key concept is component scope.

An Etch component is separated from the page, template, or loop where it is used. It does not automatically inherit the local data surrounding it.

Suppose a page contains a post loop:

{#loop posts as post}
  <!-- A Post Card component is placed here -->
{/loop}

Directly inside that page loop, this may work:

{post.title}

Putting the same expression inside the Post Card component does not make the loop’s local post object available there. The component has its own scope and does not automatically know what post means.

To cross that boundary, you explicitly pass the current post into an Object Prop. Inside the component, you access it through the prop:

{props.post.title}

The Object Prop is the bridge between the page’s local data and the component’s isolated scope.

According to the official Object Prop documentation, a component can access global data such as this, site, and url by default, but local loop or object data must be explicitly passed in.

What we will build

We will build a reusable Post Card containing:

  • A featured image
  • A publication date
  • A post title
  • An optional excerpt
  • Links to the post

The page will handle the post loop. On each iteration, it will pass the current post object into the card.

Conceptually, the data flow looks like this:

Page or template
└── post loop
    └── current post object
        └── Post Card Object Prop
            └── props.post

Step 1: Create the Object Prop

Open the Post Card in the component editor and add a new prop.

Use these values:

Type:  Object
Label: Post
Key:   post

The label is the user-facing name shown when someone edits a component instance. The key is the name used in dynamic expressions.

Because the key is post, the base reference is:

props.post

Choose a key that describes the entity the component represents. Names such as post, event, product, person, and location make expressions easy to understand. Avoid vague keys such as data, object, or thing when a more meaningful name is available.

Step 2: Map values inside the component

An Object Prop represents the whole incoming object, but you will usually display its individual properties rather than the object itself.

For a post, the mappings might look like this:

Title

{props.post.title}

Excerpt

{props.post.excerpt}

Permalink

href="{props.post.permalink.relative}"

Featured image

The correct path depends on the shape of the incoming image data. It might be a direct value:

src="{props.post.featuredImage}"

Or the image might itself be an object:

src="{props.post.featuredImage.url}"
alt="{props.post.featuredImage.alt}"

The expression must match the actual structure of the object you pass in.

Etch supports visual mapping for visible content and copy-and-paste mapping for values such as href, src, alt, and custom attributes. See Mapping Component Props for the current interface workflow.

Understanding nested data paths

Consider this simplified object:

{
  "title": "My Article",
  "author": {
    "name": "Steve Walker",
    "profile": {
      "url": "/authors/steve/"
    }
  }
}

If this object is passed into the post prop, its values become:

{props.post.title}
{props.post.author.name}
{props.post.author.profile.url}

The path follows the shape of the object:

props
└── post
    ├── title
    └── author
        ├── name
        └── profile
            └── url

There is no automatic translation or field renaming. If the object contains featuredImage, an expression looking for image will not find it.

Step 3: Add preview data

While you are editing the component itself, there may be no real post loop around it. That means an expression such as this has no live object to read:

{props.post.title}

Without sample data, the component can look empty or broken while you design it. The Object Prop’s code editor solves this problem by accepting placeholder JSON.

Add preview data that matches the structure your component expects:

{
  "title": "Understanding Etch Object Props",
  "excerpt": "Learn how to pass complete data objects into reusable Etch components.",
  "date": "July 16, 2026",
  "featuredImage": {
    "url": "https://placehold.co/1200x675",
    "alt": "A sample placeholder image"
  },
  "permalink": {
    "relative": "#"
  }
}

This JSON gives the component something useful to display while you build it. It also acts as fallback content until a source object is selected.

It is important to understand what preview data does not do:

Preview JSON does not query WordPress or define the live data source.

The live object will be selected on the component instance when you use the component on a page or in a template.

Preview data must match the expected structure

Suppose the component uses this path:

{props.post.permalink.relative}

This preview data matches:

{
  "permalink": {
    "relative": "#"
  }
}

This does not:

{
  "url": "#"
}

The component is looking for permalink, then relative. A top-level url property is a different structure.

Step 4: Build the Post Card markup

Here is a conceptual version of the complete component:

<article class="post-card">
  <a
    class="post-card__image-link"
    href="{props.post.permalink.relative}"
    aria-label="Read {props.post.title}"
  >
    <img
      class="post-card__image"
      src="{props.post.featuredImage.url}"
      alt="{props.post.featuredImage.alt}"
    >
  </a>

  <div class="post-card__content">
    <p class="post-card__date">
      {props.post.date}
    </p>

    <h2 class="post-card__title">
      <a href="{props.post.permalink.relative}">
        {props.post.title}
      </a>
    </h2>

    {#if props.post.excerpt}
      <p class="post-card__excerpt">
        {props.post.excerpt}
      </p>
    {/if}
  </div>
</article>

Notice that the component never references the page’s loop alias directly. Every incoming post value begins with the component interface: props.post.

A quick note about braces

Use curly braces when inserting a dynamic expression into normal content or an attribute:

{props.post.title}
href="{props.post.permalink.relative}"

When you are already inside a loop or condition expression, do not add a second pair of braces:

{#if props.post.excerpt}
  <p>{props.post.excerpt}</p>
{/if}

Correct:

{#loop props.content.items as item}

Incorrect:

{#loop {props.content.items} as item}

Step 5: Pass the live object into the component

Return to the page or template containing the post loop and place the Post Card component inside it.

Conceptually, the structure is:

{#loop posts as post}
  <!-- Post Card component -->
{/loop}

Select the component instance. Its attributes panel will contain an input named Post, matching the Object Prop label.

Choose the current post object as the source for that input. Etch’s Object Prop input is a combobox and can automatically populate from parent or ancestor loops. A single-loop setup may work immediately; in nested loops, confirm that the selected source is the correct one.

The mapping is now:

Current post from the page loop → props.post inside the component

On each iteration of the loop, the page supplies a different post object. The component markup remains unchanged.

For three posts, the process is effectively:

Iteration 1: props.post = first post object
Iteration 2: props.post = second post object
Iteration 3: props.post = third post object

The expression {props.post.title} therefore renders a different title each time, even though the component uses the same markup for every card.

Using arrays inside an Object Prop

An Object Prop can also accept an array or an object containing an array. For example:

{
  "items": [
    {
      "title": "First item"
    },
    {
      "title": "Second item"
    }
  ]
}

If the Object Prop key is content, the component can loop over the nested array:

{#loop props.content.items as item}
  <h3>{item.title}</h3>
{/loop}

Here, props.content.items identifies the array. Once the loop begins, item represents the current array entry.

Object Props and conditional content

Object values can also be used in conditions.

Given this data:

{
  "title": "Sample Post",
  "isFeatured": true
}

You can display a badge only for featured posts:

{#if props.post.isFeatured}
  <span>Featured</span>
{/if}

Or show an excerpt only when one exists:

{#if props.post.excerpt}
  <p>{props.post.excerpt}</p>
{/if}

Object Props vs. individual props

An Object Prop is not the only way to make a component dynamic. You could create separate props for each required value.

Individual-prop approach

Create props such as:

postTitle
postExcerpt
postImage
postLink

Then use them inside the component:

<h2>{props.postTitle}</h2>
<p>{props.postExcerpt}</p>
<a href="{props.postLink}">Read more</a>

When the component is used, each prop is connected to the corresponding dynamic value.

Object Prop approach

Create one post Object Prop and access its fields:

<h2>{props.post.title}</h2>
<p>{props.post.excerpt}</p>
<a href="{props.post.permalink.relative}">Read more</a>

Then connect the complete current post object to the component instance.

When to use each approach

Use individual props when:

  • The component needs only a few values.
  • Each value should be independently replaceable.
  • The component may receive differently shaped data sources.
  • The component should work equally well with static and dynamic content.
  • You want a small, explicit component interface.

Use an Object Prop when:

  • Several values come from the same object.
  • The component represents a particular entity.
  • You need access to nested data.
  • Passing each field separately would be repetitive.
  • You may need more properties from the same object later.

A Post Card naturally represents a post, so a post Object Prop is often a good fit. A generic Button, however, is usually clearer with separate props such as label, url, and variant.

Object Props vs. Loop Props

These prop types solve different problems.

Object Prop: the page loops

The loop lives outside the component. The component receives one current item:

Page loops through posts
└── Post Card receives one post as props.post

Conceptually:

{#loop posts as post}
  <PostCard />
{/loop}

Loop Prop: the component loops

A Loop Prop gives the component an internal loop source. The component performs the looping itself:

{#loop props.postLoop as post}
  <article>
    <h2>{post.title}</h2>
  </article>
{/loop}

The shortest way to remember the difference is:

Object Prop: The page loops; the component receives one item.
Loop Prop:   The component receives a loop source and performs the loop.

See the official Loop Prop documentation for additional syntax and examples.

Object Props vs. Group Props

Object and Group Props can both produce dot-based paths, but their roles differ.

An Object Prop transports existing structured data from outside the component:

{props.post.title}
{props.post.author.name}

A Group Prop organizes related component inputs under a shared key. Its nested properties are defined as part of the component’s interface and remain individually editable on an instance:

{props.hero.title}
{props.hero.description}
{props.hero.buttonText}

A helpful distinction is:

Object Prop: transports an external object.
Group Prop:  defines and organizes related component settings.

Group Props can also operate as repeaters in current Etch versions. See the official Group Prop documentation for details.

Common mistakes and how to fix them

1. Referencing the external loop alias inside the component

This may be valid on the page:

{post.title}

It does not automatically resolve inside the component. Use the Object Prop instead:

{props.post.title}

2. Treating preview JSON as the live data source

Preview JSON does not fetch posts. It provides sample or fallback data while no external source object is connected.

The fix is to select the live object on the component instance.

3. Using a path that does not match the object

This component expression:

{props.post.image.url}

does not match this data:

{
  "featuredImage": {
    "url": "image.jpg"
  }
}

Use the matching path:

{props.post.featuredImage.url}

4. Passing one property instead of the complete object

If the Object Prop expects a post object but receives only post.title, then props.post contains a string rather than the complete post.

This cannot work:

{props.post.permalink.relative}

The title string does not contain a permalink. Connect the complete current post object instead.

5. Selecting the wrong source in a nested loop

Consider this structure:

{#loop categories as category}
  {#loop category.posts as post}
    <!-- Post Card component -->
  {/loop}
{/loop}

The component may be able to choose between the outer category object and the inner post object. A Post Card should receive the inner post.

Always verify the Object Prop’s selected source when a component sits inside nested loops.

6. Adding extra braces inside a condition or loop

Incorrect:

{#if {props.post.excerpt}}

Correct:

{#if props.post.excerpt}

The condition already provides the surrounding braces.

7. Overusing Object Props

Passing an entire post object into every small child component can create unnecessary coupling.

For example, this makes a button dependent on post-shaped data:

href="{props.post.permalink.relative}"

A generic Button component is more reusable when it accepts a direct URL:

href="{props.url}"

Use an Object Prop when the component truly represents the object—not merely because one property happens to come from it.

A practical decision rule

Ask this question:

Does the component represent a specific thing?

If the answer is yes, an Object Prop may be a natural fit:

Post Card        → props.post
Event Card       → props.event
Product Card     → props.product
Person Card      → props.person
Location Card    → props.location

If the component is a generic interface element, individual props are often clearer:

Button           → props.label, props.url, props.variant
Badge            → props.text, props.color
Notice           → props.heading, props.message, props.isDismissible

The goal is not to use the fewest props possible. The goal is to create the clearest, most reusable component interface.

A simple video demonstration sequence

If you are following along with the video—or planning your own demonstration—the concept is easiest to teach in this order:

  • Create a post loop and show that {post.title} works directly in the loop.
  • Put that expression inside a component and demonstrate the scope problem.
  • Add an Object Prop with the key post.
  • Replace {post.title} with {props.post.title}.
  • Add matching preview JSON so the component renders while being edited.
  • Place the component inside the loop and select the current post as its object source.
  • Add a nested path such as {props.post.permalink.relative}.
  • Briefly compare this setup with separate props and a Loop Prop.

This sequence moves from the problem to the solution and makes the role of the Object Prop visible at every step.

Conclusion

An Etch Object Prop is the doorway through which a complete external data object enters a component’s isolated scope.

The workflow is straightforward:

  • Create an Object Prop with a meaningful key such as post.
  • Read values inside the component through paths such as props.post.title.
  • Add preview JSON that matches the expected object structure.
  • Place the component in its real context and connect the live object.
  • Verify nested paths and loop sources, especially in nested loops.

Object Props are most valuable when a component represents a structured entity and needs multiple values from it. Used thoughtfully, they reduce repetitive prop mapping while keeping components portable, understandable, and reusable.

Further reading

Leave a Reply

Your email address will not be published. Required fields are marked *

In this Article