How Shopify Liquid renders meta tags: a technical guide for SEOs
Where titles, descriptions, canonicals and robots tags come from in a Shopify theme, how Liquid builds them and how to audit and fix them safely.

Why the way Shopify builds meta tags matters
On most Shopify stores, nobody writes the title tag of a page by hand in HTML. A single piece of template code decides what appears in the head of every product, collection, article and page, and it fills in the blanks from fields that merchants edit in the admin. That design is convenient, and it is also why a mistake in one file can quietly damage thousands of URLs at once. A doubled brand name in the title, a missing canonical tag or an unescaped quotation mark in a description is not a one-page problem. It is a template problem, and it ships to every page that uses the template.
This guide explains how Liquid, Shopify's templating language, produces the elements that matter most for search: the title, the meta description, the canonical link, robots directives and the Open Graph tags that control how a page looks when it is shared. It is written for SEOs who have to review a theme, brief a developer or diagnose an odd result in Search Console, and for developers who want to understand what the SEO team is asking for. It sits inside our wider coverage of Shopify SEO, and it assumes you already know the basics of why titles and descriptions matter. If you are looking for a broader list of common Shopify problems, start with Shopify SEO problems and fixes.

One caution before we begin. Themes differ, Shopify changes its platform over time, and the code below is a simplified illustration of common patterns, not a copy of any one theme. Always read the actual files of the theme you are working with, test on a duplicate theme and check Shopify's current documentation for the objects and filters mentioned here.
Where the tags come from: theme.liquid and the head
Every Shopify theme has a layout file, usually called theme.liquid, that wraps all other templates. Everything in its head section appears on every page that uses the layout, which is almost all of them. A simplified head often looks like this:
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ page_title }}{% unless page_title contains shop.name %} – {{ shop.name }}{% endunless %}</title>
{% if page_description %}
<meta name="description" content="{{ page_description | escape }}">
{% endif %}
<link rel="canonical" href="{{ canonical_url }}">
{% render 'social-meta-tags' %}
{{ content_for_header }}
</head>
Four things are worth noticing. First, the title is not stored in the layout. It comes from an object called page_title, which Shopify fills in depending on which page is being rendered. Second, the description is wrapped in a condition, so if the object is empty no description tag is printed at all. Third, the canonical link uses another object, canonical_url, which Shopify calculates. Fourth, content_for_header is a required placeholder where Shopify and installed apps inject their own scripts and tags. Anything inside it is outside the control of the layout file, which becomes important when apps add their own meta tags.
Many themes move groups of tags into snippets, which are small reusable files included with the render tag. A snippet named meta-tags or social-meta-tags might print the Open Graph and Twitter tags. This is tidy, but it means that to understand what a page outputs you may have to follow several files.
The Liquid objects that matter for SEO
Liquid is a template language, so it works by reading objects that Shopify supplies and printing their values. A short list covers most of what an SEO needs.
| Object | What it contains | SEO use |
|---|---|---|
| page_title | The title for the current page, using the SEO title field if one is set and the page's own name if not | Printed in the title tag and often in social tags |
| page_description | The meta description for the current page, from the SEO description field or a fallback | Printed in the meta description |
| canonical_url | The preferred URL for the page, calculated by Shopify | Printed in the canonical link |
| shop.name and shop.description | The store name and store description from settings | Used in title suffixes and some fallbacks |
| request.page_type and template | Which type of page is rendering, such as product, collection or article | Lets a theme change tags for each type |
| current_page and paginate | The page number in a paginated listing | Used to adjust titles on page two onward |
| current_tags | Tags applied to a filtered collection or blog view | Often appended to titles for tag pages |
| page_image | The main image for the current page | Used in Open Graph and Twitter tags |
The value of understanding these is diagnostic. If a page prints the wrong title, the question is whether the SEO title field was empty, whether a fallback was used, or whether the theme overrides it. Every symptom has one of those three causes.
Title tags: how page_title is built and where it goes wrong
Shopify decides page_title by looking at the SEO title field in the admin for each product, collection, page, article or blog. If the field is empty, Shopify falls back to the item's name, such as the product title. For the home page it uses the title set in the online store preferences. The theme then prints it, often with the store name added at the end.
That arrangement produces a handful of typical faults.
The brand name appears twice
If a merchant types "Trail Running Shoes | Ridge Outfitters" into the SEO title field and the theme appends the store name unconditionally, the result is "Trail Running Shoes | Ridge Outfitters – Ridge Outfitters". The usual fix is the unless condition shown above, which adds the store name only when it is not already present. It is a small guard, but it needs to be in the layout.
The title is too long, or too short
Google does not impose a hard character limit. It displays as many characters as fit in the available width and may rewrite titles that it considers unhelpful. The admin editor shows recommended limits, and they are sensible guidance, not law. Long titles get cut off, which can hide the most persuasive words. Very short titles waste an opportunity to match the way people search. Aim for a title that states the page's subject clearly in the first few words and fits in roughly 55 to 60 characters where possible.
Pagination and tags create near-duplicates
Themes commonly add "Page 2" and tag names to titles on paginated or filtered views. That is helpful, because it differentiates them, but check that your theme does it. Without it, page two of a collection has the same title as page one, and tag views are indistinguishable from the base collection.
Default titles on pages nobody edited
Because the fallback uses the item's own name, a product named "Item 4831 Blue" gets a title of exactly that. Whole catalogs can ship with titles that read like inventory codes. This is not a Liquid error. It is a content gap that Liquid is faithfully reproducing, and the fix is a title strategy. Some stores generate titles from structured fields, such as brand, product type and a key attribute, using a template rule or bulk editing tools.
Meta descriptions: fallbacks, escaping and empty values
Descriptions are where Liquid details bite hardest, because descriptions often contain quotation marks, ampersands and line breaks.
Always escape the value
The description is printed inside an HTML attribute. If a merchant writes: Our "best-selling" boots, and the theme prints it without escaping, the quotation marks close the attribute early and break the tag. Liquid's escape filter converts such characters into safe equivalents. A theme that prints page_description without the filter is a bug waiting for the first quotation mark. Most current themes use the filter, but older or heavily customized themes sometimes do not.
Understand the fallback
If the SEO description field is empty, Shopify may fall back to a truncated version of the product or collection description, or to the shop description, depending on the page type and theme. Fallbacks that pull in the beginning of a long product description are often unhelpful, because the first lines may be a size chart or a shipping note. Review what actually prints on a sample of pages in each template, not just what the admin shows.
Decide what to do when there is nothing to print
The condition around the description tag means a page without a value gets no tag. Google then writes its own snippet from the page content. That is acceptable, and often better than a poor generic description. The important point is to avoid printing the same sitewide description on every page, which is the worst of both worlds. A duplicated description tells search engines nothing and may waste the space users read.
Strip HTML and line breaks
If a description includes markup or line breaks from a rich text editor, filters such as strip_html and strip_newlines help produce clean plain text. Combine them with truncate when you are building descriptions from longer fields, and remember to escape afterwards.
Canonical tags and the duplicate URL problem
Shopify's URL structure creates duplicates by design. A product can be reached at its own address, such as /products/trail-shoe, and also through each collection that contains it, such as /collections/mens/products/trail-shoe. Variants can add a query string such as ?variant=123. Tags create more addresses, and sorting or filtering adds parameters.
The platform's answer is the canonical tag. By default, canonical_url for a product viewed inside a collection points to the plain /products/ address, and canonical_url for a variant URL points to the product without the parameter. This is why the theme should print canonical_url exactly as given, with no changes. Common mistakes include:
- Hardcoding the canonical. Building it from request.path or a manually assembled string can strip the domain, keep unwanted parameters or break on pages in other markets.
- Removing the canonical tag. Some developers delete it because an app prints one. Check the rendered source to be sure exactly one canonical tag remains.
- Linking internally to the longer collection-scoped product URLs. The canonical tag will usually consolidate signals, but a clean internal linking structure sends the clearest signal. Many themes link products with the within parameter, and a small Liquid change, using the product's own URL without it, makes internal links point at the canonical address.
- Printing different canonicals on mobile and desktop. With responsive themes this is rare, but custom builds sometimes introduce it.
A related topic is our guide to automated and manual collections, which looks at how collections multiply the number of URLs on a store.

Robots directives in the layout
Shopify generates a robots.txt file for the store and, since 2021, lets merchants customize it through a Liquid template called robots.txt.liquid. The default file already blocks several low-value areas, such as cart, checkout and some sorting and search URLs, but it does not block everything a store might want to keep out of the index. Keeping tag-filtered views, search result pages or app-generated pages out of the index is a job for meta robots tags, which the layout can print conditionally.
{% if template contains 'search' or current_tags %}
<meta name="robots" content="noindex, follow">
{% endif %}
The example illustrates the principle: Liquid knows which template is rendering and whether tags are active, so the layout can add a noindex directive to those views only. It is a powerful lever and a risky one. A condition that is slightly too broad could noindex all collection pages, and a theme update can overwrite the change. Always test with a copy of the theme and verify the rendered tags on real URLs before you publish.
Understand also how robots.txt and noindex interact. A page blocked in robots.txt cannot be crawled, so a noindex tag on it will never be seen. If a page needs to be removed from the index, allow it to be crawled until it has dropped out. We cover this trade-off in noindex versus disallow for filtering systems.
Open Graph and Twitter tags
Open Graph tags control the title, description and image shown when a page is shared on social platforms and in messaging apps. They do not affect rankings directly, but they affect click-through from shares, and a broken preview looks careless. A typical snippet prints og:site_name, og:url, og:title, og:type, og:description and og:image, usually from page_title, page_description, canonical_url and page_image.
Common issues are missing images, images that are too small, wrong types, and tags that duplicate those printed by an app. Check shared links in the debugging tools that the major platforms provide, and confirm each page type prints a sensible image. Product pages should use the main product image, collections should use the collection image if one exists and the home page should use a branded image.
Structured data and Liquid
Structured data is not a meta tag, but it is generated by the same kind of code and often goes wrong in the same way. Many current Shopify themes use a filter that converts a product object into JSON-LD, and print it on product pages. Problems arise when the theme prints one version, a review or SEO app prints another and the page ends up with two overlapping product definitions that disagree on price or availability. Google tolerates some duplication but may ignore conflicting data, so decide which source is authoritative and disable the others.
Validate with Google's Rich Results Test and monitor the enhancements reports in Search Console. Remember that markup must match what visitors can see. If the structured data shows a price that is not shown on the page, it breaks Google's guidelines.
When apps add their own tags
Apps can inject tags in two ways. They can write into content_for_header, which prints inside the head, or they can edit theme files directly, which adds code to the theme. SEO apps in particular may add titles, descriptions, canonical tags and structured data. If your theme already prints these, you may end up with two of each.
The check is simple and should be routine. View the page source of a product, collection and article page and search for the tags. Count how many title tags, meta descriptions and canonical links appear. There should be exactly one of each. If there are duplicates, decide whether the app or the theme owns the tag, then remove the other. We look at the performance side of apps in our guide to the impact of Shopify apps on Total Blocking Time and Core Web Vitals.
Also watch for leftovers. Uninstalling an app does not always remove the code it added to a theme. Old snippets can keep printing tags for services you no longer use, and they sometimes load scripts that no longer do anything. A clean-up of the theme code after removing an app is good hygiene.
Markets, languages and hreflang
If a store sells in several countries or languages through Shopify's international features, the layout also has to deal with alternate versions of each page. Shopify's markets feature can output hreflang annotations automatically in many themes, using the available languages and domains. Check that the output is present in the rendered head, that each URL points to a page that really exists and that each page references itself and its alternates. Errors here create confusion about which version to show to which searcher. The structure decisions behind this are covered in subfolders versus subdomains for Shopify international SEO.
How to audit meta tags in a Shopify theme
You do not need to read every line of a theme to audit its tags. A structured approach finds most problems quickly.
- Crawl the live store. Use a crawler to collect titles, descriptions, canonicals, robots directives and H1s for all URLs. Sort by template type.
- Look for patterns. Duplicate titles across hundreds of URLs point to a template fallback or a missing field. Missing descriptions point to the conditional or to empty fields. Canonicals that do not match the URL point to a template or app issue.
- Check sample pages by type. Open view-source for a product, a collection, a paginated collection page, a tagged collection page, a blog article, a page and the home page. Verify each tag by eye.
- Compare rendered and raw HTML. If an app injects tags with JavaScript, they will not appear in the raw source but may appear in the rendered DOM. Use the URL Inspection tool in Search Console to see what Google has rendered.
- Read theme.liquid and the snippets it renders. Find where each tag is produced and whether it uses the objects described above, with proper escaping.
- Check Search Console. The Pages report and the page indexing details will reveal canonical conflicts, "duplicate without user-selected canonical" statuses and pages excluded by noindex.
- Record fixes as theme changes. Make edits on a duplicate theme, review the code difference, test and then publish.
Our technical SEO audit checklist places this inside a full audit, and the SEO audit service page describes how we deliver one.
A safer pattern for titles and descriptions
While every store differs, a defensible pattern for the head looks like this. It is illustrative and should be adapted and tested.
{%- liquid
assign seo_title = page_title | strip_html | escape
assign seo_desc = page_description | strip_html | strip_newlines | truncate: 300 | escape
-%}
<title>{{ seo_title }}{% unless page_title contains shop.name %} – {{ shop.name | escape }}{% endunless %}</title>
{%- if seo_desc != blank -%}
<meta name="description" content="{{ seo_desc }}">
{%- endif -%}
<link rel="canonical" href="{{ canonical_url }}">
What this does well: it cleans and escapes the values once, avoids printing an empty description, guards against a doubled brand name and leaves the canonical exactly as Shopify calculates it. What it deliberately leaves out: any logic that changes the canonical, and any code that hardcodes the store name where the field already contains it.
Beyond the code, the more valuable practice is governance. Decide who is allowed to edit theme files, keep changes in a log, test on a duplicate theme and re-crawl after each release. Most Shopify meta tag disasters are not caused by clever code. They are caused by an unreviewed change to a shared file.

A worked example: finding a template-wide fault
Consider a fictional store selling outdoor gear. After a theme update, Search Console shows a drop in clicks across product pages, though rankings have barely moved. A crawl of the store gives the clue: 4,200 product URLs now share identical titles that begin with "Outdoor Gear Store".
The investigation follows a predictable path. The team opens the product template and finds that the update added a line to the layout that prints the shop name first and the page title second, wrapped in a condition that was supposed to apply only to the home page. Because the condition referred to the wrong template name, it matched every page. The store name now dominates every title, pushing the product name to the end, where it is more likely to be cut off in results.
The fix is a three-line change in the layout, tested on a duplicate theme. The team confirms the rendered titles on a sample of each template type, publishes the change and re-crawls. Two weeks later, click-through rates on product pages recover. Nothing about the content or the links had to change. The fault lived in one shared file, which is exactly why template-level auditing pays off.
The lessons are general. Look for patterns across many URLs rather than inspecting single pages. Trace each pattern to a template, an app or a field. Make the smallest change that fixes the root cause. And verify in the rendered output, not in the admin screen.
A pre-publish checklist for theme changes
Whenever you or a developer edit the head of a Shopify theme, run through the same list before the change goes live.
- Work on a duplicate theme and preview it with real product, collection and article URLs.
- Check one of each page type: home, collection, paginated collection, tagged collection, product, product with a variant parameter, article, blog index, content page and the search page.
- Count the tags: exactly one title, one meta description (or none, by design), one canonical and the expected robots directive.
- Validate escaping by testing a product whose title and description contain quotation marks and ampersands.
- Test other languages and markets if the store uses them, including the hreflang output.
- Compare structured data in the Rich Results Test and confirm that only one product definition appears.
- Review the diff between the live and duplicate themes so that no unintended changes ship.
- Keep a rollback copy of the previous theme and know how to restore it quickly.
- Re-crawl after publishing and compare titles, descriptions and canonicals with the pre-change export.
- Watch Search Console for the next few weeks for new exclusions, canonical conflicts or changes in impressions.
Treat this list as part of the release process, not an optional extra. The time it takes is small compared with the cost of discovering a store-wide fault from a traffic report a month later.
Common mistakes
- Printing the description without escaping it. A single quotation mark breaks the tag.
- Appending the store name unconditionally. Titles end up with the brand twice.
- Hardcoding canonicals. It can break on variants, markets and paginated pages.
- Leaving two sources of tags. A theme and an SEO app both printing titles, descriptions or schema.
- Using one sitewide description on every page. It tells search engines nothing.
- Noindexing too broadly. A loose condition can remove important pages from the index.
- Editing the live theme. Changes should be tested on a duplicate first.
- Ignoring uninstalled app code. Old snippets can keep printing tags and loading scripts.
- Trusting the admin view only. What matters is what prints in the rendered page.
- Not re-crawling after a release. Problems that begin in a template spread silently.
Shopify Plus, headless stores and migrations
Larger stores sometimes run on Shopify Plus, which adds checkout and automation features but uses the same Liquid templating for the storefront. The principles here apply equally. If you are moving to Shopify from another platform, tag handling is one of the first things to plan, because titles, descriptions and canonicals must be carried across or rebuilt. See Shopify Plus SEO and platform migration SEO.
Stores built with a headless approach, where the storefront is a separate application that fetches data from Shopify, do not use Liquid for rendering at all. Meta tags are produced by whatever framework builds the front end, and the concerns shift to server-side rendering and the correctness of the data passed to the head. The audit method, however, is unchanged: look at the rendered output, one template at a time.
How we help
Our Shopify work begins with the rendered output, because that is what search engines read. We crawl the store, group URLs by template, trace each tag back to the theme file or app that prints it and give your developer a precise list of changes, with the expected effect of each. We test on a duplicate theme, verify the live tags after release and monitor Search Console for side effects. See our Shopify SEO service, learn about ecommerce SEO services more broadly or request a free SEO audit of your store. This guide is part of a series, and the next one explains how to handle international store structure.
Summary
- Shopify builds titles, descriptions and canonicals in the theme layout from objects such as page_title, page_description and canonical_url.
- Escape every value, avoid doubled brand names and never print an empty or sitewide generic description.
- Print canonical_url as Shopify supplies it and link internally to canonical product URLs.
- Use conditional meta robots tags carefully, and remember that robots.txt blocks crawling but noindex needs crawling to be seen.
- Make sure only one source, the theme or an app, prints each tag and each block of structured data.
- Audit by crawling, sampling each template type and checking rendered source, then test changes on a duplicate theme.
Related guides
Ecommerce SEOShopify international SEO: subfolders vs subdomains
Compare subfolders, subdomains and country domains for Shopify international SEO, with hreflang rules, localization advice and a decision framework.
Read the guide
Ecommerce SEOSEO best practices for Shopify product tags: avoid thin content and indexation bloat
How Shopify product and blog tags create thin pages, how to diagnose indexation bloat and how to fix it with links, canonicals, noindex and a tag taxonomy.
Read the guideEcommerce SEOShopify SEO problems and how to fix them
The most common Shopify SEO problems and how to fix them: duplicate URLs, thin collections, tag and filter pages, app bloat, speed, structured data and migrations.
Read the guideFrequently asked questions
Where do I edit the meta title and description in Shopify?
Edit them in the search engine listing section of each product, collection, page or article in the admin. The theme reads those fields through Liquid objects such as page_title and page_description and prints them in the head.
Why does my Shopify page show the store name twice in the title?
The theme probably appends the store name to every title, and the SEO title field already contains it. A condition that adds the store name only when it is not already present in page_title fixes this.
Does Shopify add canonical tags automatically?
Yes. Themes print canonical_url, which Shopify calculates, and for products viewed through a collection or a variant it normally points to the plain product address. Check that your theme prints it unchanged and that an app is not printing a second one.
Can I noindex certain pages in Shopify?
Yes. You can add a conditional meta robots tag in the theme layout for specific templates or tag views, and you can customize robots.txt with the robots.txt.liquid template. Test carefully, because an over-broad condition can remove important pages from the index.
Why does my page have two canonical tags or two meta descriptions?
Usually an SEO or other app prints its own tags in addition to the theme. Decide which one owns each tag and remove the other, then check the rendered source of each template.
Do I need to know Liquid to do Shopify SEO?
Not for everyday work, but understanding how the objects fill the head helps you diagnose template-wide problems and brief a developer precisely.
Not sure where your site stands?
Send us your website and we will tell you what we would fix first, including if SEO is not your best next step.