Blog Posts Grid for Homepage

Your latest blog posts in a clean grid with images, dates and excerpts.

One section file Homepage Edit in the theme editor

Important: Before making any changes to your theme, duplicate it in Online Store > Themes so you have a backup.

Blog posts earn search traffic, but only if shoppers and search engines can find them. This section shows your latest posts on the homepage, or any page, in a grid with featured images, dates and short excerpts.

Preview

What you'll build

From the blog

View all posts

12 Oct 2026

How to care for linen

A short excerpt from the post appears here.

3 Oct 2026

Our autumn lookbook

A short excerpt from the post appears here.

21 Sep 2026

Meet the makers

A short excerpt from the post appears here.

Preview with the default settings. Colours, text and layout can all be changed in the theme editor.

Install

Add it to your store in 4 steps

  1. 1

    Open your theme code

    In Shopify admin go to Online Store > Themes. Next to the theme you want to edit, click the three dots and choose Edit code.

  2. 2

    Create the section

    In the Sections folder click Add a new section, name it lt-blog-posts-grid, delete the placeholder code, paste in the code below and click Save.

  3. 3

    Add it in the theme editor

    Click Customize, go to Home page, click Add section and choose Blog posts grid.

  4. 4

    Make it yours

    Change the settings in the sidebar, drag the section where you want it, and click Save.

sections/lt-blog-posts-grid.liquid · 146 lines
{%- comment -%}
  Blog posts grid for the homepage by LAUNCHTIP
  https://launchtip.com/free-shopify-sections-code
{%- endcomment -%}
{%- liquid
  assign blog = section.settings.blog
  if blog == blank
    assign blog = blogs.news
  endif
-%}

{%- style -%}
  #lt-{{ section.id }} { padding: {{ section.settings.padding }}px 0; }
  #lt-{{ section.id }} .lt-bg__top { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 20px; }
  #lt-{{ section.id }} .lt-bg__top h2 { margin: 0; }
  #lt-{{ section.id }} .lt-bg__all { color: inherit; white-space: nowrap; }
  #lt-{{ section.id }} .lt-bg__grid { display: grid; gap: 24px; grid-template-columns: 1fr; }
  @media (min-width: 750px) { #lt-{{ section.id }} .lt-bg__grid { grid-template-columns: repeat({{ section.settings.columns }}, minmax(0, 1fr)); } }
  #lt-{{ section.id }} .lt-bg__card { color: inherit; text-decoration: none; display: flex; flex-direction: column; }
  #lt-{{ section.id }} .lt-bg__media { aspect-ratio: 3 / 2; border-radius: 10px; overflow: hidden; background: #f3f3f3; }
  #lt-{{ section.id }} .lt-bg__media img, #lt-{{ section.id }} .lt-bg__media svg { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.3s ease; }
  #lt-{{ section.id }} .lt-bg__card:hover img { transform: scale(1.03); }
  #lt-{{ section.id }} .lt-bg__meta { margin: 12px 0 4px; font-size: 0.8em; text-transform: uppercase; letter-spacing: 0.05em; opacity: 0.6; }
  #lt-{{ section.id }} .lt-bg__title { margin: 0 0 6px; font-size: 1.1em; line-height: 1.3; }
  #lt-{{ section.id }} .lt-bg__excerpt { margin: 0; opacity: 0.8; font-size: 0.95em; }
{%- endstyle -%}

<div id="lt-{{ section.id }}" class="page-width">
  <div class="lt-bg__top">
    {%- if section.settings.heading != blank -%}
      <h2 class="h2">{{ section.settings.heading }}</h2>
    {%- endif -%}
    {%- if blog != blank and section.settings.view_all_label != blank -%}
      <a class="lt-bg__all" href="{{ blog.url }}">{{ section.settings.view_all_label }}</a>
    {%- endif -%}
  </div>

  <div class="lt-bg__grid">
    {%- if blog != blank and blog.articles_count > 0 -%}
      {%- for article in blog.articles limit: section.settings.limit -%}
        <a class="lt-bg__card" href="{{ article.url }}">
          <div class="lt-bg__media">
            {%- if article.image != blank -%}
              {{ article.image | image_url: width: 800 | image_tag: loading: 'lazy', widths: '400, 600, 800', sizes: '(min-width: 750px) 33vw, 100vw', alt: article.title }}
            {%- else -%}
              {{ 'image' | placeholder_svg_tag }}
            {%- endif -%}
          </div>
          {%- if section.settings.show_date or section.settings.show_author -%}
            <p class="lt-bg__meta">
              {%- if section.settings.show_date -%}{{ article.published_at | time_tag: format: 'date' }}{%- endif -%}
              {%- if section.settings.show_date and section.settings.show_author %} &middot; {% endif -%}
              {%- if section.settings.show_author -%}{{ article.author }}{%- endif -%}
            </p>
          {%- endif -%}
          <h3 class="lt-bg__title">{{ article.title }}</h3>
          {%- if section.settings.show_excerpt -%}
            <p class="lt-bg__excerpt">
              {%- if article.excerpt != blank -%}{{ article.excerpt | strip_html | truncatewords: 22 }}{%- else -%}{{ article.content | strip_html | truncatewords: 22 }}{%- endif -%}
            </p>
          {%- endif -%}
        </a>
      {%- endfor -%}
    {%- elsif request.design_mode -%}
      <p>Pick a blog with at least one published post in the section settings.</p>
    {%- endif -%}
  </div>
</div>

{% schema %}
{
  "name": "Blog posts grid",
  "tag": "section",
  "class": "lt-bg-section",
  "settings": [
    {
      "type": "text",
      "id": "heading",
      "label": "Heading",
      "default": "From the blog"
    },
    {
      "type": "blog",
      "id": "blog",
      "label": "Blog"
    },
    {
      "type": "range",
      "id": "limit",
      "label": "Posts to show",
      "min": 1,
      "max": 12,
      "step": 1,
      "default": 3
    },
    {
      "type": "range",
      "id": "columns",
      "label": "Columns on desktop",
      "min": 1,
      "max": 4,
      "step": 1,
      "default": 3
    },
    {
      "type": "checkbox",
      "id": "show_date",
      "label": "Show date",
      "default": true
    },
    {
      "type": "checkbox",
      "id": "show_author",
      "label": "Show author",
      "default": false
    },
    {
      "type": "checkbox",
      "id": "show_excerpt",
      "label": "Show excerpt",
      "default": true
    },
    {
      "type": "text",
      "id": "view_all_label",
      "label": "View all link label",
      "default": "View all posts"
    },
    {
      "type": "range",
      "id": "padding",
      "label": "Vertical padding",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "default": 48
    }
  ],
  "presets": [
    {
      "name": "Blog posts grid"
    }
  ]
}
{% endschema %}
Customization

What you can change in the theme editor

Setting Default
Heading From the blog
Blog —
Posts to show 3
Columns on desktop 3
Show date On
Show author Off
Show excerpt On
View all link label View all posts
Vertical padding 48px
Good to know

Tips for setting it up

  • Pick the blog in the section settings. If you leave it empty, your default News blog is used.
  • Give every post a featured image so the grid looks even.
  • Use the article excerpt field in Shopify to control exactly what appears under each title.

Further reading: Read the LAUNCHTIP blog

FAQ

Frequently asked questions

Can I show posts from more than one blog?

Add the section once for each blog.

Can I filter by tag?

Not in this version. Create a separate blog for the posts you want to feature, or edit the loop to check article.tags.

Will it help SEO?

Linking to your posts from the homepage helps search engines find and value them, and gives shoppers a reason to stay.

More free sections

New

Recently Viewed Products

Shows each shopper the products they looked at, so they can get back to them in a tap.

New

Sticky Add-to-Cart Bar

A bar that slides up when the buy button scrolls off screen, with price and variant.

New

Variant-Aware Content

Text and images that change when the shopper picks a different colour or size.

Explore More Free Sections

Discover more code snippets to enhance your Shopify store.

View All Sections
SellUp Increase AOV with Upsells