Skip to content

Tags Template

The tags template renders pages that display all posts matching one or more tags. Tags provide a flexible, user-defined way to organize and filter blog content.

└── theme
└── templates
└── tags.liquid

Tag pages are accessible at:

  • /tags/:tag - Single tag
  • /tags/:tag+tag2 - Multiple tags (AND logic)

For example:

  • /tags/featured - Posts tagged “featured”
  • /tags/news+featured - Posts tagged BOTH “news” AND “featured”

The tags template receives these variables:

An array of tag strings being filtered:

PropertyTypeDescription
tagsarrayTag names being filtered

An array of posts matching ALL specified tags:

PropertyTypeDescription
postsarrayPosts matching the tag filter

Each post in the array has access to all standard post properties.

{% layout 'layouts/default.liquid' %}
{% capture content_for_layout %}
<div class="tags-page">
<header class="tags-header">
<h1>
Posts tagged:
{% for tag in tags %}
<span class="tag-badge">{{ tag }}</span>
{% unless forloop.last %} + {% endunless %}
{% endfor %}
</h1>
<p class="post-count">{{ posts.size }} {% if posts.size == 1 %}post{% else %}posts{% endif %}</p>
</header>
<div class="posts-list">
{% if posts.size > 0 %}
{% for post in posts %}
<article class="post-card">
{% if post.image %}
<img
src="{{ post.image | image_url: width: 400, height: 250 }}"
alt="{{ post.title }}"
loading="lazy"
>
{% endif %}
<div class="post-card__content">
<h2>
<a href="/posts/{{ post.slug }}">{{ post.title }}</a>
</h2>
{% if post.publishDate %}
<time datetime="{{ post.publishDate }}">
{{ post.publishDate | date: '%B %d, %Y' }}
</time>
{% endif %}
{% if post.description %}
<p>{{ post.description | truncate: 150 }}</p>
{% endif %}
</div>
</article>
{% endfor %}
{% else %}
<p class="no-posts">No posts found with these tags.</p>
{% endif %}
</div>
</div>
{% endcapture %}
<div class="active-tags">
<span>Filtering by:</span>
{% for tag in tags %}
<span class="tag tag--active">{{ tag }}</span>
{% endfor %}
</div>
<div class="tag-filters">
{% for tag in tags %}
{% assign other_tags = '' %}
{% for t in tags %}
{% if t != tag %}
{% if other_tags != '' %}
{% assign other_tags = other_tags | append: '+' %}
{% endif %}
{% assign other_tags = other_tags | append: t %}
{% endif %}
{% endfor %}
<span class="tag-pill">
{{ tag }}
{% if other_tags != '' %}
<a href="/tags/{{ other_tags }}" class="remove-tag" aria-label="Remove {{ tag }} filter">×</a>
{% else %}
<a href="/blog" class="remove-tag" aria-label="Remove {{ tag }} filter">×</a>
{% endif %}
</span>
{% endfor %}
{% if tags.size > 1 %}
<a href="/blog" class="clear-all">Clear all</a>
{% endif %}
</div>
{% for post in posts %}
<article class="post-card">
<h3><a href="/posts/{{ post.slug }}">{{ post.title }}</a></h3>
{% if post.tags.size > 0 %}
<div class="post-tags">
{% for tag in post.tags %}
<a href="/tags/{{ tag | handleize }}"
class="tag {% if tags contains tag %}tag--active{% endif %}">
{{ tag }}
</a>
{% endfor %}
</div>
{% endif %}
</article>
{% endfor %}
{% layout 'layouts/default.liquid' %}
{% capture content_for_layout %}
<div class="tags-page">
{# Breadcrumb navigation #}
<nav class="breadcrumb" aria-label="Breadcrumb">
<ol>
<li><a href="/">Home</a></li>
<li><a href="/blog">Blog</a></li>
<li aria-current="page">
Tagged:
{% for tag in tags %}
{{ tag }}{% unless forloop.last %}, {% endunless %}
{% endfor %}
</li>
</ol>
</nav>
{# Page header #}
<header class="tags-header">
<h1>
{% if tags.size == 1 %}
Posts tagged "{{ tags.first }}"
{% else %}
Posts tagged:
{% endif %}
</h1>
{# Active tag filters #}
{% if tags.size > 1 %}
<div class="active-filters">
{% for tag in tags %}
{% comment %} Build URL without this tag {% endcomment %}
{% assign remaining_tags = '' %}
{% for t in tags %}
{% if t != tag %}
{% if remaining_tags != '' %}
{% assign remaining_tags = remaining_tags | append: '+' %}
{% endif %}
{% assign remaining_tags = remaining_tags | append: t %}
{% endif %}
{% endfor %}
<span class="filter-tag">
{{ tag }}
{% if remaining_tags != '' %}
<a href="/tags/{{ remaining_tags }}" class="remove" title="Remove this filter">×</a>
{% else %}
<a href="/blog" class="remove" title="Remove this filter">×</a>
{% endif %}
</span>
{% endfor %}
<a href="/blog" class="clear-filters">Clear all filters</a>
</div>
{% endif %}
<p class="results-count">
{{ posts.size }} {% if posts.size == 1 %}result{% else %}results{% endif %}
</p>
</header>
{# Posts listing #}
{% if posts.size > 0 %}
<section class="tags-posts">
<div class="post-grid">
{% for post in posts %}
<article class="post-card">
<a href="/posts/{{ post.slug }}" class="post-card__link">
{% if post.image %}
<img
src="{{ post.image | image_url: width: 400, height: 250 }}"
alt="{{ post.title }}"
class="post-card__image"
loading="lazy"
>
{% endif %}
<div class="post-card__content">
{% if post.categories.size > 0 %}
<span class="post-card__category">{{ post.categories.first }}</span>
{% endif %}
<h2 class="post-card__title">{{ post.title }}</h2>
<div class="post-card__meta">
{% if post.publishDate %}
<time datetime="{{ post.publishDate }}">
{{ post.publishDate | date: '%b %d, %Y' }}
</time>
{% endif %}
{% if post.authors.size > 0 %}
<span class="author">by {{ post.authors.first.name }}</span>
{% endif %}
</div>
{% if post.description %}
<p class="post-card__excerpt">
{{ post.description | truncate: 120 }}
</p>
{% endif %}
{# Show post tags, highlighting active ones #}
{% if post.tags.size > 0 %}
<div class="post-card__tags">
{% for tag in post.tags %}
<span class="mini-tag {% if tags contains tag %}mini-tag--active{% endif %}">
{{ tag }}
</span>
{% endfor %}
</div>
{% endif %}
</div>
</a>
</article>
{% endfor %}
</div>
</section>
{% else %}
<div class="tags-empty">
<h2>No Posts Found</h2>
<p>
No posts match
{% if tags.size == 1 %}
the tag "{{ tags.first }}".
{% else %}
all of these tags: {{ tags | join: ', ' }}.
{% endif %}
</p>
<p>Try removing some filters or browse all posts.</p>
<a href="/blog" class="btn btn--secondary">Browse All Posts</a>
</div>
{% endif %}
{# Navigation #}
<nav class="tags-nav">
<a href="/blog" class="back-link">
&larr; Back to Blog
</a>
</nav>
</div>
{% endcapture %}
{% schema %}
{
"name": "tags",
"settings": [
{
"type": "select",
"name": "layout",
"label": "Posts Layout",
"options": [
{ "value": "grid", "label": "Grid" },
{ "value": "list", "label": "List" }
],
"defaultValue": "grid"
},
{
"type": "checkbox",
"name": "show_post_tags",
"label": "Show Tags on Each Post",
"defaultValue": true
}
]
}
{% endschema %}
{# In post.liquid template #}
{% if post.tags.size > 0 %}
<div class="post-tags">
<span class="tags-label">Tags:</span>
{% for tag in post.tags %}
<a href="/tags/{{ tag | handleize }}" class="tag">{{ tag }}</a>
{% endfor %}
</div>
{% endif %}
{# Link to posts with multiple tags #}
<a href="/tags/featured+news">Featured News</a>
<a href="/tags/tutorial+beginner">Beginner Tutorials</a>
{# Display all available tags #}
{% if all_tags.size > 0 %}
<aside class="tag-cloud">
<h3>Browse by Tag</h3>
<div class="tags">
{% for tag in all_tags %}
<a href="/tags/{{ tag.slug }}" class="tag">
{{ tag.title }}
</a>
{% endfor %}
</div>
</aside>
{% endif %}
FeatureTagsCategories
URL/tags/:tag/categories/:slug
Multiple filterYes (+ syntax)No
HierarchyFlatFlat
User-definedYesAdmin-defined
Best forFlexible labelingPrimary classification

Create variations for different tag presentations:

templates/
├── tags.liquid # Default tags template
├── tags.minimal.liquid # Simple list view
└── tags.magazine.liquid # Magazine-style layout