2.0 Beta

Smootify 2.0 is in public beta. Your 1.x store keeps working. Move when you want.

What changed

Build the collection page

The page of each collection in your store. Covers the page URL, the collection details, and the two ways to list its products, cards rendered by Astro or search & discovery.

v2.0 beta
Open .md
On this page
  1. How it fits together
  2. 1. The template page and its URL
  3. 2. The collection details
  4. 3. List the products with Astro
  5. 4. Or list them with search & discovery
  6. 5. Products of other collections
  7. Before you publish

A collection page is src/pages/collections/[slug].astro: one page for each entry of the collections content collection. The collection’s name, description and image come from the entry. The products can come from two places: the entry’s own products, rendered by Astro as product cards, or search & discovery, which loads them live from Shopify with filters and sorting. This guide covers both and helps you choose.

Note

Before you start, Smootify must be installed on the site (Install Smootify in Astro) and your products and collections loaded as content collections: see Content from Shopify. Each product’s collections field references its collections, and each collection has its shopifyId field.

How it fits together

What Smootify needs:

  • one product card per product: a smootify-product element with the product’s id;
  • for search & discovery, a smootify-search-discovery element that knows the collection.

What is up to you:

  • the layout of the page, the collection header, the card design, the classes and the styles;
  • which way you list the products. You can also start with cards rendered by Astro and move to search & discovery later: the card design stays the same.

The two ways side by side:

Cards rendered by AstroSearch & discovery
Products come fromthe content collection, at buildShopify, live
Filters and sortingnonechosen by the visitor
Orderthe collection’s order in Shopify, as loadedthe collection’s order in Shopify, until the visitor picks a sort
A new productshows after the next buildshows without a build
Needsnothing morethe Search & discovery add-on

1. The template page and its URL

Create src/pages/collections/[slug].astro with a getStaticPaths that maps the collections content collection to { params: { slug: entry.id }, props: { entry } }. The entry’s id is the Shopify handle, so each page is at /collections/ followed by the handle, such as /collections/summer: the same address as in Shopify.

Smootify builds links to collection pages, for example with product="collections" on a product card. It expects them under /collections/. For another route, name the page folder after it, such as src/pages/categories/[slug].astro, and set collectionsBase to that name in the userOptions of the integration in astro.config.mjs: see the Smootify options.

2. The collection details

The header of the page is plain HTML. Write the entry’s name in a heading, its description (HTML) with set:html, and its image and imageAlt in an <img>. For the title and the meta description, give the entry to <Seo type="collection" entry={c} />: it uses seoTitle and seoDescription, and falls back to the name and the description. See Content from Shopify.

Smootify adds nothing here: these fields change when the content is loaded again, at the next build.

3. List the products with Astro

  1. Read the products of the collection in the frontmatter of the page: (await getEntries(c.products)).filter(Boolean). The products field needs the loader option withProducts: true: see Content from Shopify.
  2. Wrap each product in an element with the class sm-dyn-item, the boundary of the card, and inside it add a smootify-product with data-id set to the product’s shopifyId.
  3. Design the card inside smootify-product: see Product cards.
---
const c = entry.data;
const products = (await getEntries(c.products)).filter(Boolean);
---
{products.map((p) => (
  <div class="sm-dyn-item">
    <smootify-product data-id={p.data.shopifyId}>
      <a product="url" href={`/products/${p.id}/`}>{p.data.name}</a>
      <smootify-price><div data-prop="price">{p.data.priceFormatted}</div></smootify-price>
    </smootify-product>
  </div>
))}

The link and the name are in the HTML before Smootify loads, so search engines read them. Smootify then writes the same values from Shopify.

The list shows what the content collection holds, in the order of the collection in Shopify. Slice it to set a limit, such as products.slice(0, 24). A product added to the collection in Shopify appears after the next build. Price, stock and the add-to-cart form inside each card are always live, because Smootify loads them from Shopify.

4. Or list them with search & discovery

Use search & discovery when the page needs filters or sorting chosen by the visitor, when the collection is large, or when the products must follow the order set in Shopify.

  1. Add a smootify-search-discovery element to the page.
  2. Give it data-collection with the collection’s Shopify ID: c.shopifyId, the numeric ID or the full ID, never the handle.
  3. Inside it, render the real product cards as in step 3: an sm-dyn-item with a smootify-product for each of the first products. Render only as many cards as limit.
---
const limit = 24;
---
<smootify-search-discovery data-collection={c.shopifyId} limit={limit}>
  <div filter="count">{products.length}</div>
  <div>
    {products.slice(0, limit).map((p) => (
      <div class="sm-dyn-item">
        <smootify-product data-id={p.data.shopifyId}>
          <a product="url" href={`/products/${p.id}/`}>{p.data.name}</a>
          <smootify-price><div data-prop="price">{p.data.priceFormatted}</div></smootify-price>
        </smootify-product>
      </div>
    ))}
  </div>
  <button type="button" data-action="load">Load more</button>
</smootify-search-discovery>

The count and the load more button above are optional. Smootify takes the first .sm-dyn-item as the card template, and rewrites the whole list from its results. The server cards stay as they are until the first results, so search engines see real products and the page keeps its height while it loads. When the results are the same products in the same order, as the first page served from the seed is, Smootify keeps the drawn cards: nothing flashes on the first load. Otherwise it replaces the list in one step. No placeholder card is needed. Every card is a copy of the first one, so give each element a Smootify attribute such as product="title", not only a value from the entry.

The first page of results comes from the page’s seed, with no request to Shopify, when the cards match it: the same limit on the element and in the code that picks the cards, the collection’s own order with no sort of your own, and the same unavailable-products as the element. See First load.

With data-collection:

  • the products come in the order the collection has in Shopify, until the visitor picks a sort;
  • the collection is locked: the reset button keeps it, and it stays out of the page address;
  • the text search (filter-search) looks inside the collection. For an exact search on a large collection, tag its products and add data-tag: see Search inside a collection.

Filters, sorting, pagination and the empty state are in Filters, sorting and pagination.

5. Products of other collections

To show a few products of another collection, such as “New in” on the home page, read that collection’s entry in the frontmatter and render its first products as in step 3, or use data-id="specific-collection": see Product lists.

Before you publish

On the dev server and on your *.workers.dev address, the Smootify debugger lists the elements that are out of place on the page. Turn it on with Alt⇧ ShiftD, or open the page with ?smootify-debug.

Check these first

  • Every collection page shows every product. The page reads the whole products collection, not the products of the entry. Read c.products.
  • A new product is missing from the list. The page shows what the content collection held at the last build. Build again, or use search & discovery, which reads Shopify directly.
  • Search & discovery shows nothing. It needs a smootify-product card inside, or it is removed. On the live domain it also needs the Search & discovery add-on.
  • Every card shows the same name or image. Inside search & discovery, every card is a copy of the first one, so text that has no Smootify attribute is copied from it. Add product="title", variant="image" and the other attributes to the card.
  • A search on a big collection misses products. Only its first 2,000 products are compared with the search. Tag them and use data-tag: see Search inside a collection.
  • Collection links lead to a page that does not exist. Your collection pages are not under /collections/. Set collectionsBase in the userOptions of the integration.
  • The list reshuffles at load. The server cards are not in the collection’s own order, or there are more of them than limit.

    ↑ ↓ to moveEnter to openEsc to close