Collection Component
The Collection component is a built-in CWA resource that acts as a configurable proxy to any other resource's collection endpoint. An admin creates a Collection, points it at a resource IRI, sets page size and default query parameters, and the front-end renders the results — with pagination, filtering, and real-time updates.
Enabling
Enabled by default. To disable:
silverback_api_components:
enabled_components:
collection: false
Creating a Collection
POST /component/collections:
{
"resourceIri": "/page_data/blog_articles",
"perPage": 6,
"defaultQueryParameters": {
"order[createdAt]": "desc"
}
}
| Field | Type | Description |
|---|---|---|
resourceIri | string | The collection endpoint to proxy (must pass the ResourceIri validator) |
perPage | int|null | Maximum items per page. null uses the API Platform default |
defaultQueryParameters | array|null | Query params appended to every proxied request — ordering, filters, etc. |
The Response
The collection property in the response is a full Hydra collection:
{
"@id": "/component/collections/018e-...",
"@type": "Collection",
"resourceIri": "/page_data/blog_articles",
"perPage": 6,
"defaultQueryParameters": { "order[createdAt]": "desc" },
"collection": {
"@context": "/contexts/BlogArticle",
"@id": "/page_data/blog_articles?order[createdAt]=desc",
"@type": "hydra:Collection",
"hydra:member": [ /* resource objects */ ],
"hydra:totalItems": 24,
"hydra:view": {
"hydra:first": "/page_data/blog_articles?page=1",
"hydra:last": "/page_data/blog_articles?page=4",
"hydra:next": "/page_data/blog_articles?page=2"
}
}
}
The collection field is read-only (#[ApiProperty(writable: false)]). The bundle populates it by proxying the request to resourceIri with defaultQueryParameters merged in.
Using in a Fixture
From BlogScaffoldPart.php in the template app — creating a blog listing collection and placing it in a page's component group:
$collection = new Collection();
$collection->setPerPage(8);
$collection->setResourceIri(
$this->iriConverter->getIriFromResource(
BlogArticleData::class,
UrlGeneratorInterface::ABS_PATH,
(new GetCollection())->withClass(BlogArticleData::class) )
);
$collection->setDefaultQueryParameters(['order[createdAt]' => 'desc']);
$cwa->page('blog-list', 'PrimaryPageTemplate', layout: 'main', route: '/blog-articles', routeName: 'blog-articles-page',
configure: function (PageBuilder $p) use ($collection) {
$p->title('Blog');
$p->group('primary')->add($collection); }
);
resourceIri must be a collection IRI, so pass a GetCollection operation bound to the class with ->withClass() — an item operation produces the wrong IRI. And to place the collection on a page you call add() on an existing group builder; $cwa->component($collection)->group('...') does the opposite, declaring a group inside the Collection component, which leaves it unplaced and never rendered.perPage vs API Platform Pagination
perPage sets the default page size for the proxied request — it is not a hard cap. The bundle injects it as the items-per-page filter, then merges the incoming query string over the top, so any matching parameter in the request wins.
That means enabling pagination_client_items_per_page on the proxied resource is all you need to let users change the page size: ?itemsPerPage=… then overrides perPage, and perPage acts as the default when no value is supplied. The same merge applies to defaultQueryParameters — request parameters override them, including with an empty string, so a default search term can be cleared by the client.
On the Front-End
Use useCwaComponent with the withCollection() plugin in the Vue component. It unwraps collection.hydra:member, exposes totalPages, and provides goToNextPage / goToPreviousPage helpers — see Collections & Pagination for the full reference.
Admin: Setting Up a Collection in the CMS
- Add the Collection component to a component group via the admin panel
- The manager tab lets you search and select the
resourceIri - Set
perPageanddefaultQueryParametersas needed - The collection renders immediately — no deploy required