Collections

Collections let you define custom content types with flexible schemas. Products, team members, FAQs, testimonials, portfolio items — anything your site needs.

How Collections Work

Each collection has a slug, a display name, and contains items. Items store their data as flexible JSON — you define the fields that make sense for your content type.

For example, a "Team" collection might have items with name, role, and photo fields. A "Products" collection might have title, price, and description.

Fetching Collections

List all collections
const res = await fetch(`${CMS_URL}/api/public/collections`, {
  headers: { "x-api-key": CMS_API_KEY },
});
const { collections } = await res.json();
// [{ slug: "team", name: "Team Members", itemCount: 5 }, ...]
Fetch items in a collection
const res = await fetch(
  `${CMS_URL}/api/public/collections/team?sortBy=order&sortOrder=asc`,
  { headers: { "x-api-key": CMS_API_KEY } }
);
const { items, pagination } = await res.json();
// items[0].data = { name: "John Doe", role: "CEO", photo: "https://..." }

Pagination & Sorting

Collection items support pagination and sorting. Use limit and offset for pagination, and sortBy / sortOrder for ordering:

Paginated request
// Fetch items 11-20, sorted by newest first
const url = new URL(`${CMS_URL}/api/public/collections/products`);
url.searchParams.set("limit", "10");
url.searchParams.set("offset", "10");
url.searchParams.set("sortBy", "createdAt");
url.searchParams.set("sortOrder", "desc");

const res = await fetch(url, {
  headers: { "x-api-key": CMS_API_KEY },
});
const { items, pagination } = await res.json();
// pagination = { total: 42, limit: 10, offset: 10 }

Rendering Collection Items

Example: Team grid
async function TeamPage() {
  const res = await fetch(
    `${process.env.CMS_URL}/api/public/collections/team`,
    { headers: { "x-api-key": process.env.CMS_API_KEY! } }
  );
  const { items } = await res.json();

  return (
    <div className="grid grid-cols-3 gap-6">
      {items.map((member) => (
        <div key={member.slug}>
          <img src={member.data.photo} alt={member.data.name} />
          <h3>{member.data.name}</h3>
          <p>{member.data.role}</p>
        </div>
      ))}
    </div>
  );
}

Next Steps