Skip to content

Collection pages

Collection pages are pages generated automatically from your data — one page per blog post, one page per product, one page per team member. Instead of manually creating hundreds of pages, you define a template once, and build awesome (powered by Eleventy) creates each page at publish time.

This page explains the concept from a designer's perspective. Full technical details are in the developer section.

How collection pages work

Step 1: Create a template page — Design a page that shows one item (a single blog post, product, or team member). Use CMS data binding to pull the item's fields.

Step 2: Mark it as a collection page — In page settings, set a pagination query that tells build awesome which data to use (e.g., "all blog posts") and which field to use as the page URL (e.g., "slug").

Step 3: Publish — When you publish, build awesome generates one HTML page per item, using the template. A blog with 50 posts produces 50 pages.

The URLs are dynamic: A blog post with slug "hello-world" becomes https://yoursite.com/blog/hello-world. Another post with slug "my-story" becomes https://yoursite.com/blog/my-story.

Setting up a collection page (example: blog)

Step 1: Create a page named blog-post (or similar)

This page is your template. Design it to show:

  • Post title (bind to post → title)
  • Post excerpt or content (bind to post → content)
  • Publication date (bind to post → date)
  • Featured image (bind to post → featured_image)
  • Author name (bind to post → author → name)

The exact fields depend on your WordPress setup, but each binding references the current item being rendered.

Step 2: Configure page settings

  1. In the Pages panel, click the gear icon (⚙) next to the page name
  2. Open Page Settings
  3. Look for Pagination or Collection section
  4. Set Query to the data source (e.g., posts)
  5. Set Permalink field to the field that becomes the URL (e.g., slug)

After publishing, build awesome will:

  • Fetch all posts from your WordPress API
  • For each post, render the template page
  • Use the post's slug to create the URL: /blog/<slug>/

Step 3: Publish and verify

Publish your site. Build awesome generates all the pages. Visit one:

  • https://yoursite.com/blog/hello-world — shows the post with slug "hello-world"
  • https://yoursite.com/blog/my-story — shows the post with slug "my-story"

Each page is a static HTML file, generated at publish time. No dynamic rendering in the browser.

Understanding pagination queries

The pagination query is a GraphQL expression that returns a list of items.

Examples:

  • posts — all posts
  • posts → where(status = "published") — only published posts
  • posts → where(category = "news") → sort(date) — news posts sorted by date
  • pages → where(template = "portfolio") — custom pages of type "portfolio"

The query runs once during publishing. Each item in the result becomes one page.

The permalink field is which field from your data becomes the page URL.

Common choices: - slug — custom URL slug (recommended) - id — numeric ID - title — post title (less ideal; special characters in titles can cause URL issues)

If you use slug and your post has slug: "my-article", the page URL is /blog/my-article (assuming the page is named blog-post in the /blog/ folder).

Dynamic segments and folder structure

Collection pages can be nested in folders to create hierarchical URLs.

Example: product collections

  1. Create a folder /products/
  2. Create a page /products/product-detail
  3. Set the pagination query to products
  4. Set the permalink field to slug

URLs become: /products/coffee-beans/, /products/dark-roast/, etc.

Nested example: category → product

  1. Create a folder /category/
  2. Inside it, create /products/
  3. Create a page /category/products/product-detail
  4. Set pagination to products
  5. Permalink field: slug

URLs might become: /category/electronics/products/laptop-123/ (if categories are also paginated).

Accessing pagination data in the template

On a collection page template, the current item is available as a data context. Your bindings use this context.

In a blog post template: - post → title — the current post's title - post → author → name — the current post's author - post → date — the current post's date

In a product template: - product → name — the current product's name - product → price — the current product's price - product → description — the current product's description

The exact variable name depends on your setup. It's usually singular (post, product, item) even though the query fetches multiple items. During rendering of each page, one item at a time is in context.

Common uses for collection pages

Blog: One template, generates a page per post. Each page has the post title, content, comments, related posts, etc.

Portfolio: One template, generates a page per project. Each page shows project details, images, and case study.

E-commerce: One template, generates a page per product. Each page shows product image, price, description, reviews, related products.

Team members: One template, generates a page per team member. Each page shows bio, photo, contact info, social links.

Docs/Knowledge Base: One template, generates a page per article. Each page shows the article content with navigation to related articles.

Limitations and considerations

  • Collection pages are static. They're generated once at publish time. If you add a new post and want it on your site, you must publish again.
  • Build time scales with data size. A collection with 1,000 items takes longer to build than one with 10 items.
  • Preview shows the template, not all pages. In the Silex editor, you see the template page with sample data. You don't preview all 100 generated pages.
  • Dynamic interactions are limited. Collection pages can't fetch new data when a user visits. They're static HTML. For truly dynamic sites, you'd need a backend or a different approach.

Troubleshooting

"Pages aren't generating" — Check the pagination query. Make sure it returns results (test in GraphQL if possible). Check the permalink field exists and has values.

"URLs are wrong" — Verify the permalink field and folder structure. The URL is built from folder name + page name + permalink value.

"Pagination query returns no results" — Your API query might be wrong. Check that the data source is connected and the query syntax is correct. Test it in the GraphQL editor.

"Some pages have wrong content" — Check that your template bindings reference the right data context. If you hardcoded data instead of using bindings, all pages will be identical.

Learn more


Quiz

Q1: What does a collection page do?

  • A) Creates a dynamic page that fetches data each time a user visits
  • B) Generates one static HTML page per item in your data
  • C) Shows a list of all items (like a blog archive)
Answer

B) Generates one static HTML page per item in your data — Collection pages are static. Build awesome creates them at publish time. No dynamic fetching on the client side.

Q2: You want to create individual pages for each product in your e-commerce store. What do you set up first?

  • A) A collection page template showing one product's details
  • B) A loop component showing all products
  • C) An API endpoint for products
Answer

A) A collection page template showing one product's details — Design a template for a single product. During publishing, build awesome clones it for each product.

Q3: In the pagination query, you set posts → where(status = "published"). What does this do?

  • A) Shows only published posts in the editor
  • B) Generates pages only for published posts
  • C) Hides draft posts from the site's search
Answer

B) Generates pages only for published posts — The pagination query filters the data before build awesome generates pages. Only matching items get pages.

Q4: Your blog posts have a field called slug (e.g., "hello-world"). You set it as the permalink field. What URL will the post get?

  • A) /blog/<post-id>/
  • B) /blog/<post-title>/
  • C) /blog/hello-world/
Answer

C) /blog/hello-world/ — The permalink field determines the dynamic part of the URL. The post's slug value becomes the URL segment.

Q5: After setting up a collection page and publishing, you add a new post to WordPress. What happens?

  • A) The new post page appears automatically on your site
  • B) You must publish again to generate a page for the new post
  • C) The new post appears as a dynamic page (not static)
Answer

B) You must publish again to generate a page for the new post — Collection pages are static and generated at publish time. New data requires a new build/publish.

Edit this page on GitLab