Talk strategy
Expert reviewed

How to Create Programmatic SEO Titles in Shopify with Metaobjects and Liquid

5 min read
Chat with ChatGPT

SEO title tags are one of the most critical elements of your e-commerce site’s on-page SEO.

How to create programmatic SEO titles in Shopify with metaobjects and Liquid

If you're running an e-commerce store with hundreds or thousands of products, you're not writing unique title tags for every page. You shouldn't have to. But each page does need a distinct, descriptive title - duplicate or generic titles hurt your search visibility and your click-through rates.

The fix is programmatic titles. Define a pattern once, and let Shopify fill in the details for every product and collection automatically. Change the pattern, and it updates across your entire site.

This guide walks through how to set that up using Liquid, metafields, and metaobjects - all built into Shopify, no apps required.

The building blocks

Before we get into the setup, it's worth understanding the three things we're working with.

Liquid is Shopify's templating language. It's the code that generates your storefront pages, pulling in data like product titles and prices and rendering them as HTML. We'll use it to build the <title> tag dynamically.

Metafields are custom fields you can add to products, collections, pages, and other resources. They let you store extra information beyond Shopify's defaults. We'll use a metafield on each product or collection to point to a specific title template.

Metaobjects are reusable custom data structures made up of multiple fields. Think of them as content blocks you define once and reference wherever you need them. For our purposes, a metaobject entry holds the title pattern - something like Buy {product_title} Online | {shop_name}. Update the pattern in one place, and every page using it picks up the change.

In short: metaobjects hold the template, metafields link the template to specific pages, and Liquid does the work of swapping placeholders for real data.

Step 1: Override the default title tag

Shopify themes typically generate the <title> tag using a combination of the page title and shop name. The default code in most themes looks something like this:

<title>
{{ page_title }}{% if current_tags %} – {{ 'general.meta.tags' | t: tags: (current_tags | join: ', ') }}{% endif %}
{% if current_page != 1 %} – {{ 'general.meta.page' | t: page: current_page }}{% endif %}
{% unless page_title contains shop.name %} – {{ shop.name }}{% endunless %}
</title>

That's functional, but it's static. We want to replace it with our own logic.

Head to Online Store > Themes > Edit Code. In your Snippets folder, create a new snippet called seo-title-tag. Then open your layout/theme.liquid file, find the existing <title>…</title> block, and replace it with:

{% render 'seo-title-tag' %}

Your title will be blank until we add the logic, but the hook is in place.

As a quick sanity check, you can drop something basic into the snippet to confirm it's working:

<title>
{% if template == "product" %}
{{ product.title }} | {{ shop.name }}
{% elsif template == "collection" %}
{{ collection.title }} | {{ shop.name }}
{% else %}
{{ page_title }} – {{ shop.name }}
{% endif %}
</title>

That's a decent starting point, but we want proper templates with placeholders - not hardcoded formats. So let's build those.

Step 2: Create a metaobject for title templates

Go to Content > Metaobjects in your Shopify admin and click Add definition. Name it something clear like "SEO Title Template".

Add a field called "Pattern" (or "Title Template") with a content type of Text (single line). This is where your title format string will live. Make sure storefront access is enabled so your Liquid code can read the data.

Save the definition, then create your first entry. Click into the "SEO Title Template" definition and add an entry with a pattern like:

Buy {product_title} Online | {shop_name}

You can create multiple entries for different use cases. A brand-focused pattern might look like {product_title} by {vendor} - {shop_name}. Give each entry a clear name so you can tell them apart when assigning them later.

The beauty of this approach is centralised control. If you decide to restructure your title format down the line, you edit the metaobject entry once and every linked page updates automatically.

Step 3: Link templates to pages with metafields

Now we need to connect those templates to individual products, collections, and pages. That's what metafields are for.

Go to Settings > Custom data > Products. Click Add definition and create a metafield called "SEO Title Template". For the type, choose Metaobject, then select "SEO Title Template" as the allowed definition. Save it.

This gives every product a new field in the admin where you can pick which title template to use. Open any product, scroll to the metafields section, and select the appropriate template entry. You can bulk-edit metafields across products if you want to assign the same template to everything at once.

Repeat this process for Collections and Pages if you want dynamic titles on those too. You'll likely want different metaobject entries for collections - something like {collection_title} | {shop_name} rather than the product format.

If a product or collection doesn't have a template assigned, our code will fall back to a sensible default. Nothing breaks.

Step 4: Write the Liquid logic

This is where it all comes together. Open your snippets/seo-title-tag.liquid file and build the logic that checks for a template, replaces the placeholders, and outputs the title.

The flow is straightforward. For each page type, we check whether a metaobject template has been assigned via the metafield. If it has, we grab the pattern string and use Liquid's replace filter to swap placeholders for real data. If no template is assigned, we fall back to the default.

To access the metaobject data in Liquid, use the metafield reference with .value to get the entry, then .pattern.value to get the text field:

{% assign seo_template = product.metafields.seo.title_template.value %}
{{ seo_template.pattern.value }}

For placeholder replacement, chain replace filters:

{{ pattern | replace: '{product_title}', product.title | replace: '{shop_name}', shop.name }}

You can add as many placeholders as you need - {vendor}, {collection_title}, or even custom metafield values. Just make sure the placeholder text in your metaobject pattern matches exactly what you're replacing in the Liquid code. A typo means the raw placeholder shows up on the live site.

Use the escape filter on the final output to handle any special characters (ampersands, quotes) cleanly in the HTML.

Build out the full snippet with {% if %} / {% elsif %} blocks for each template type (product, collection, page), and include a fallback {% else %} that outputs {{ page_title }} - {{ shop.name }} for anything without a template assigned.

Step 5: Test and validate

Open your store in a browser and check a product page. Right-click, view page source, and find the <title> tag. You should see your template pattern with the placeholders replaced by the actual product data.

If your template was Buy {product_title} Online | {shop_name} and the product is "Red T-Shirt" on a store called "MyStore", the HTML should show:

<title>Buy Red T-Shirt Online | MyStore</title>

Check a few different products and collections to make sure the right templates are being pulled through. If anything looks off, double-check that the metafield is assigned, the metaobject has storefront access enabled, and your placeholder strings match between the template and the Liquid code.

Why this matters commercially

This setup gives you unique, keyword-rich titles across every product and collection page without manually writing hundreds of them. You can test different title formats by updating a single metaobject entry and measuring the impact on click-through rates. And because it's all built on native Shopify features, there's no app subscription or third-party dependency to worry about.

Set it up once, and your store handles title tags on autopilot from there. The technical team can extend the Liquid code as needed, and less technical team members can manage the templates through the Shopify admin. It's a clean, scalable way to handle on-page optimisation across a growing catalogue.