> ## Documentation Index
> Fetch the complete documentation index at: https://docs.olonjs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tag Posts — inverse relation post listing for a tag page

> The Tag Posts section lists all posts for the current tag by filtering the posts collection at render time. Place it on tag detail pages after Tag Detail.

The `tag-posts` section renders the list of all posts that belong to the current tag. It implements the **inverse relation** between tags and posts: because post-to-tag membership is stored on the post (each post carries a `tags` array of references), there is no posts list stored on the tag record itself.

Instead, `tag-posts` receives both the current `Tag` object and the full `posts` collection, then filters the posts map at render time — keeping only entries whose `tags` array contains the current tag's key. The result is a dynamically computed list of posts for the active tag page.

Use this section on `tags/[slug]` pages, placed after [Tag Detail](/reference/sections/tag-detail).

## Data fields

<ParamField body="item" type="Tag" required>
  A collection reference that resolves to the current route's `Tag` object. In your page JSON, set this to `{ "$ref": "collection:current" }`. The section uses the resolved tag's `id` as the filter key when scanning the `posts` map.
</ParamField>

<ParamField body="posts" type="Record<string, Post>" required>
  A reference to the full posts collection, provided as a string-keyed map of `Post` objects. In your page JSON, set this to `{ "$ref": "../../collections/posts/posts.json" }`. The section iterates this map and retains posts whose `tags` array includes the current tag key.
</ParamField>

<ParamField body="title" type="string">
  Optional heading rendered above the post list — for example `"Posts on this topic"`. When omitted, no heading is shown.
</ParamField>

<ParamField body="emptyLabel" type="string">
  Optional message displayed when no posts carry the current tag — for example `"No posts carry this tag yet."`. When omitted and the filtered list is empty, the section renders nothing.
</ParamField>

## Inverse relation model

OlonJS stores the tag membership relation on the post side only. Each post holds a `tags` array of resolved `Tag` objects. The tag record has no `posts` field — this keeps tag data lean and avoids duplication.

To produce a tag's post list, OlonJS passes the entire `posts` collection to this section and the component performs the filter:

```js theme={null}
postsForTag = Object.values(posts).filter(post =>
  post.tags.some(tag => tag.id === item.id)
)
```

Adding a tag reference to a post automatically makes that post appear on the tag's page — no additional data authoring is required.

## Settings fields

<ParamField body="paddingTop" type="&#x22;none&#x22; | &#x22;sm&#x22; | &#x22;md&#x22; | &#x22;lg&#x22; | &#x22;xl&#x22;">
  Vertical padding applied above the section.
</ParamField>

<ParamField body="paddingBottom" type="&#x22;none&#x22; | &#x22;sm&#x22; | &#x22;md&#x22; | &#x22;lg&#x22; | &#x22;xl&#x22;">
  Vertical padding applied below the section.
</ParamField>

## JSON example

The following example is taken from `tags/[slug].json`:

```json theme={null}
{
  "id": "tag-detail-posts",
  "type": "tag-posts",
  "data": {
    "title": "Posts on this topic",
    "emptyLabel": "No posts carry this tag yet.",
    "item": { "$ref": "collection:current" },
    "posts": { "$ref": "../../collections/posts/posts.json" }
  },
  "settings": {}
}
```

OlonJS resolves `collection:current` to the tag for the current route and the `$ref` path to the full posts collection. The component then filters and renders matching posts.

## Typical page usage

Place `tag-posts` as the second section on your `tags/[slug]` page, immediately after [Tag Detail](/reference/sections/tag-detail). Both sections share the same `collection:current` tag reference.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.