Collection card on collection Grid help?

Topic summary

A user encountered an empty tile in their collection grid on desktop and wanted to fill it with a promotional collection link rather than leaving it blank.

Solution Provided:
A Mageplaza support representative offered a code-based solution for the Shopify Savor theme involving:

  • Step 1: Updating the product-grid.liquid file in the snippets folder with custom code to support promo blocks
  • Step 2: Modifying the main-collection.liquid file to include promo block rendering logic and schema settings
  • Step 3: Configuring the promo banner details (title, description, button text, link) directly in the theme customizer under the ‘default collection’ section

The solution allows inserting a customizable promotional card among product cards in the collection grid. Screenshots demonstrate the configuration interface and final result showing the promo block integrated into the product grid.

Status: Resolved with working code implementation.

Summarized with AI on October 27. AI used: claude-sonnet-4-5-20250929.

Hi All, i have a empty tile in my collection on desktop. Is there a way i can add a collection tile here amongst the product cards to fill the space? Thanks

1 Like

Hi @DASCPA ,

I am from Mageplaza - Shopify solution expert.

You can either create a new product or customize the code to add a “Promo” in the empty spot.
Please let me know which theme you’re using and how you’d prefer to implement this customization.

Best regards!

1 Like

I would like to use a promo (link to another collection) using the shopify Savor theme

Hi @DASCPA

Yes, absolutely. Please follow the steps below to apply the promo in a simple and effective way:

Step 1: Update the product-grid.liquid file in the snippets folder with the following code:

{%- doc -%}
  This snippet is used to render the product grid on collection and search pages.

  @param {object} section - The section object
  @param {object} paginate - Pagination object
  @param {object} products - Array of product objects
  @param {string} [title] - Header of the collection or search results
  @param {string} children - List or grid of product cards
{%- enddoc -%}

{% capture product_card_size %}
  {% render 'util-product-grid-card-size' section: section %}
{% endcapture %}
{% assign product_card_size = product_card_size | strip %}

{% style %}
  @media (min-width: 750px) {
    {% case section.settings.layout_type %}
      {% when 'grid' %}
        .product-grid--{{ section.id }}:is(.product-grid--grid) {
          --product-grid-columns-desktop: repeat(auto-fill, minmax({{ product_card_size }}, 1fr));
        }
      {% when 'organic' %}
        {% assign large_span = 2 %}
        {% assign row_cycle = 3 %}
        {% assign product_cycle = row_cycle | times: 2 %}
        {% assign right_large_start_col = 3 %}
        .product-grid--{{ section.id }}:not([product-grid-view='zoom-out']):is(.product-grid--organic) .product-grid__item:nth-child({{ product_cycle }}n + 1) {
          grid-column: 1 / span {{ large_span }};
        }

        .product-grid--{{ section.id }}:not([product-grid-view='zoom-out']):is(.product-grid--organic) .product-grid__item:nth-child({{ product_cycle }}n + 2),
        .product-grid--{{ section.id }}:not([product-grid-view='zoom-out']):is(.product-grid--organic) .product-grid__item:nth-child({{ product_cycle }}n + 5) {
          align-self: end;
        }

        .product-grid--{{ section.id }}:not([product-grid-view='zoom-out']):is(.product-grid--organic) .product-grid__item:nth-child({{ product_cycle }}n + {{ product_cycle }}) {
          grid-column: {{ right_large_start_col }} / span {{ large_span }};
        }

        .product-grid--{{ section.id }}:not([product-grid-view='zoom-out']):is(.product-grid--organic) {
          --product-grid-columns-desktop: repeat(4, 1fr);
        }
    {% endcase %}

    /* This logic helps prevent displaying one column for an large or extra-large product card size on a small screen. We want it to display at least two columns. */
    {% case section.settings.product_card_size %}
      {% when 'extra-large' or 'large' %}
        @container product-grid (width < calc({{ product_card_size }} * 3 + {{ section.settings.columns_gap_horizontal }}px * 2)) {
          .product-grid--{{ section.id }}:is(.product-grid--grid) {
            --product-grid-columns-desktop: repeat(2, 1fr);
          }
        }
    {% endcase %}

    /* When zoomed out, fit as many 100px-wide columns as possible */
    .product-grid--{{ section.id }}:is([product-grid-view='zoom-out']) {
      --product-grid-columns-desktop: repeat(auto-fill, minmax(6.25rem, 1fr));
    }

    .product-grid--{{ section.id }}:is([product-grid-view='zoom-out']) .product-grid-view-zoom-out--details {
      display: block;
    }

    .product-grid--{{ section.id }}:is([product-grid-view='zoom-out']) .product-grid__card {
      padding-inline-start: var(--zoom-out-padding-inline-start, 0);
      padding-inline-end: var(--zoom-out-padding-inline-end, 0);
      padding-block-start: var(--zoom-out-padding-block-start, 0);
      padding-block-end: var(--zoom-out-padding-block-end, 0);
    }
  }
{% endstyle %}

  

    {% if products.size == 0 %}
      

        ## 
          {{ 'content.no_products_found' | t }}
        
        

          {{ 'content.use_fewer_filters_html' | t: link: collection.url, class: 'main-collection-grid__empty-link' }}
        

      

    {% else %}
      

      {% if title %}
        #### {{ title }}
      {% endif %}
      
        {{ children }}

        {% comment %}promo block{% endcomment %}
        {% if section.settings.show_promo_block %}
          - ### {{ section.settings.promo_block_title }}
                

  {{ section.settings.promo_block_description }}

                
                    {{ section.settings.promo_block_button_text }}
                
              

            

          
        {% endif %}
      

      
    {% endif %}
  

{% comment %}
  This script is used to set the grid view on the product grid stored in sessionStorage. Keeping it here helps us prevent seeing the default state.
{% endcomment %}
{% unless request.design_mode %}
  
{% endunless %}

{% stylesheet %}
  .product-grid {
    --product-grid-gap: var(--product-grid-gap-mobile);
    isolation: isolate;

    @media screen and (width >= 750px) {
      --product-grid-gap: var(--product-grid-gap-desktop);
    }
  }

  .product-grid slideshow-arrows .slideshow-control {
    display: none;

    @media screen and (width >= 750px) {
      display: grid;
    }
  }

  .main-collection-grid {
    padding: var(--grid--margin--mobile);

    @media screen and (width >= 750px) {
      padding: var(--padding-block-start) var(--padding-inline-end) var(--padding-block-end) var(--padding-inline-start);
    }
  }

  .main-collection-grid__empty {
    padding-block: var(--padding-6xl);
    padding-inline: var(--page-margin);
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--padding-sm);
  }

  .main-collection-grid__empty-title {
    margin: 0;
  }

  .collection-wrapper--full-width .main-collection-grid__title {
    margin-left: var(--page-margin);
  }

  .collection-wrapper--full-width-on-mobile .main-collection-grid__title {
    @media screen and (width < 750px) {
      margin-left: var(--page-margin);
    }
  }
{% endstylesheet %}

Step 2: Update the main-collection.liquid file in the sections folder with the following code:

{% liquid
  # Onboarding: When no products are available, we show placeholder items
  assign products = ''
  if request.design_mode and shop.products_count == 0
    for i in (1..16)
      assign products = products | append: ' ,'
    endfor
    assign products = products | split: ','
  endif
%}

{% javascript %}
  const url = new URL(window.location.href);
  if (url.hash) {
    document.addEventListener(
      'DOMContentLoaded',
      () => {
        const card = document.getElementById(url.hash.slice(1));
        if (card) {
          card.scrollIntoView({ behavior: 'instant' });
        }
      },
      { once: true }
    );
  }
{% endjavascript %}

{% comment %} We always render this full-width, as the child blocks have width: page/full settings {% endcomment %}

{% stylesheet %}
  .main-collection-grid {
    grid-column: var(--grid-column--mobile);
    @media screen and (width >= 750px) {
      grid-column: var(--grid-column--desktop);
    }
  }

  .collection-wrapper {
    @media screen and (width >= 750px) {
      grid-template-columns:
        1fr repeat(
          var(--centered-column-number),
          minmax(0, calc((var(--page-width) - var(--page-margin) * 2) / var(--centered-column-number)))
        )
        1fr;
    }
  }

  .collection-wrapper:has(.facets-block-wrapper--full-width),
  .collection-wrapper:has(.collection-wrapper--full-width) {
    @media screen and (width >= 750px) {
      grid-column: 1 / -1;
      grid-template-columns:
        minmax(var(--page-margin), 1fr) repeat(
          var(--centered-column-number),
          minmax(0, calc((var(--page-width) - var(--page-margin) * 2) / var(--centered-column-number)))
        )
        minmax(var(--page-margin), 1fr);
    }
  }

  .collection-wrapper:has(.facets--vertical) .facets-block-wrapper--vertical:not(.hidden) ~ .main-collection-grid {
    @media screen and (width >= 750px) {
      grid-column: var(--facets-vertical-col-width) / var(--full-width-column-number);
    }
  }

  .collection-wrapper:has(.facets-block-wrapper--vertical:not(#filters-drawer)):has(.collection-wrapper--full-width) {
    @media screen and (width >= 750px) {
      grid-column: 1 / -1;
      grid-template-columns: 0fr repeat(var(--centered-column-number), minmax(0, 1fr)) 0fr;
    }
  }

  :is(.collection-wrapper--full-width, .collection-wrapper--full-width-on-mobile)
    [product-grid-view='default']
    .product-grid__item
    .group-block {
    @media screen and (width < 750px) {
      padding-inline-start: max(var(--padding-xs), var(--padding-inline-start));
      padding-inline-end: max(var(--padding-xs), var(--padding-inline-end));
    }
  }

  :is(.collection-wrapper--full-width, .collection-wrapper--full-width-on-mobile)
    [product-grid-view='mobile-single']
    .product-grid__item
    .group-block {
    @media screen and (width < 750px) {
      padding-inline-start: max(var(--padding-xs), var(--padding-inline-start));
      padding-inline-end: max(var(--padding-xs), var(--padding-inline-end));
    }
  }
{% endstylesheet %}

{% schema %}
{
  "name": "t:names.collection_container",
  "enabled_on": {
    "templates": ["collection"]
  },
  "settings": [
    {
      "type": "select",
      "id": "layout_type",
      "label": "t:settings.type",
      "options": [
        {
          "value": "grid",
          "label": "t:options.grid"
        },
        {
          "value": "organic",
          "label": "t:options.editorial"
        }
      ],
      "default": "grid"
    },
    {
      "type": "select",
      "id": "product_card_size",
      "label": "t:settings.card_size",
      "options": [
        {
          "value": "small",
          "label": "t:options.small"
        },
        {
          "value": "medium",
          "label": "t:options.medium"
        },
        {
          "value": "large",
          "label": "t:options.large"
        },
        {
          "value": "extra-large",
          "label": "t:options.extra_large"
        }
      ],
      "default": "medium",
      "visible_if": "{{ section.settings.layout_type == 'grid' }}"
    },
    {
      "type": "select",
      "id": "mobile_product_card_size",
      "label": "t:settings.mobile_card_size",
      "options": [
        {
          "value": "small",
          "label": "t:options.small"
        },
        {
          "value": "large",
          "label": "t:options.large"
        }
      ],
      "default": "small"
    },
    {
      "type": "header",
      "content": "t:content.layout"
    },
    {
      "type": "select",
      "id": "product_grid_width",
      "label": "t:settings.width",
      "options": [
        {
          "value": "centered",
          "label": "t:options.page"
        },
        {
          "value": "full-width",
          "label": "t:options.full"
        }
      ],
      "default": "centered"
    },
    {
      "type": "checkbox",
      "id": "full_width_on_mobile",
      "label": "t:settings.full_width_on_mobile",
      "default": true,
      "visible_if": "{{ section.settings.product_grid_width != 'full-width' }}"
    },
    {
      "type": "range",
      "id": "columns_gap_horizontal",
      "label": "t:settings.horizontal_gap",
      "min": 0,
      "max": 50,
      "step": 1,
      "unit": "px",
      "default": 16
    },
    {
      "type": "range",
      "id": "columns_gap_vertical",
      "label": "t:settings.vertical_gap",
      "min": 0,
      "max": 50,
      "step": 1,
      "unit": "px",
      "default": 16
    },
    {
      "type": "range",
      "id": "padding-inline-start",
      "label": "t:settings.left_padding",
      "min": 0,
      "max": 100,
      "step": 1,
      "unit": "px",
      "default": 0
    },
    {
      "type": "range",
      "id": "padding-inline-end",
      "label": "t:settings.right_padding",
      "min": 0,
      "max": 100,
      "step": 1,
      "unit": "px",
      "default": 0
    },
    {
      "type": "header",
      "content": "t:content.section_layout"
    },
    {
      "type": "color_scheme",
      "id": "color_scheme",
      "label": "t:settings.color_scheme",
      "default": "scheme-1"
    },
    {
      "type": "range",
      "id": "padding-block-start",
      "label": "t:settings.top_padding",
      "min": 0,
      "max": 100,
      "step": 1,
      "unit": "px",
      "default": 8
    },
    {
      "type": "range",
      "id": "padding-block-end",
      "label": "t:settings.bottom_padding",
      "min": 0,
      "max": 100,
      "step": 1,
      "unit": "px",
      "default": 8
    },
    {
      "type": "header",
      "content": "Promo Block"
    },
    {
      "type": "text",
      "id": "promo_block_title",
      "label": "Promo Title",
      "default": "Special Offer",
      "info": "The title of the Block Promotion"
    },
    {
      "type": "textarea",
      "id": "promo_block_description",
      "label": "Promo Description",
      "default": "This is a limited time offer for our customers.",
      "info": "Promotion description"
    },
    {
      "type": "text",
      "id": "promo_block_button_text",
      "label": "Button Text",
      "default": "Shop Now",
      "info": "Written button calling for action"
    },
    {
      "type": "url",
      "id": "promo_block_link",
      "label": "Promo Link",
      "info": "Links when clicking the button"
    },
    {
      "type": "checkbox",
      "id": "show_promo_block",
      "label": "Show Promo Block",
      "default": true,
      "info": "Show the promotion block in Grid"
    }
  ],
  "presets": []
}
{% endschema %}

Step 3: Fill in the appropriate promo banner information in the ‘default collection’ section

*Result:

If you like this approach, don’t forget to rate it as a solution.
Best regards.