Content and SEO

Per-page titles and descriptions, redirects that keep an old address working, and posts published on your store with an RSS feed.

Written 2026-09-16, updated 2026-09-29. Three things that decide how a store is found and how much of it there is to find: per-page SEO (a title, description, canonical, share image and noindex on one product, collection, page or post), redirects (so an address you change keeps working), and posts (your own writing, published on your store with a feed). Sections 6 to 8 say what your store writes for search engines on its own: structured data, the sitemap and robots.txt, and the proof a search engine asks for. Section 9 is the store's own health check.

Everything here is live data: a change is on the storefront as soon as it is saved. None of it goes through the draft-and-publish loop the theme uses (agents.md).

1. Per-page SEO

Your store already writes a title and description for every page. An override replaces one of those tags on one page and leaves the rest alone.

An override is addressed by two things:

PartWhat it is
ownerTypeproduct, collection, page or post
ownerIdthat object's public handle: the product slug, the collection handle, the page slug, the post slug

Handles, not internal ids: the address the shopper sees is the address you write SEO for. If you rename the handle, the override moves with it (§2).

FieldLimitWhat it does
title60Replaces <title> and the og:title
metaDescription160Replaces the meta description and the og:description
canonicalhttps URLReplaces <link rel="canonical"> and the og:url
ogImageUrlhttps URLAdds an og:image, the picture that shows when the page is shared
noindextrue / falseAdds noindex,nofollow for this page only

An empty field keeps the generated tag. Set only what you want to change. An override whose fields are all empty is removed, and the page goes back to what your store writes for it. noindex can hide one page; it can never un-hide a store you hid store-wide.

Dashboard. Growth → SEO, under the store-wide settings: pick a page, type, save.

Routes. GET /api/seo?ownerType=&ownerId= reads one override, PUT with the same query saves it, DELETE removes it, and GET /api/seo?list=1 lists every override the store has. Without ownerType the route is the store-wide setting it has always been (storefront:read / storefront:write).

Tools. get_seo { ownerType?, ownerId? }, set_seo { ownerType?, ownerId?, title?, metaDescription?, canonical?, ogImageUrl?, noindex? } and list_seo_overrides.

{ "ownerType": "product", "ownerId": "blue-mug",
  "title": "Blue mug, hand thrown", "metaDescription": "A 300 ml stoneware mug, thrown and glazed in our studio.", "noindex": false }

What your store writes by default

TagRule
Title<name> · <store name> in at most 60 characters, cut at a word. When the store name leaves no room, the name stands alone. The home page uses your store-wide title, else your store name and its description when both fit.
DescriptionPlain text from the thing's own words, at most 160 characters, cut at a word. On the home page, collections, pages, posts and the blog list, text under 70 characters is followed by a short sentence built from real names (the page, your store, and on a list the things it lists) when that still fits. A product's own short text is used as written.
CanonicalYour primary address, https, with no tracking parameters. A paged list keeps ?page=N. A filtered or sorted list points to the plain list.
Share imageYour override, else the page's own first picture, else your home page picture, else your logo. With none, the page carries no image tag.
Languagelang="en". A store has one language, so pages carry no hreflang.

Never indexed. These pages say noindex: the cart, checkout, account pages, order tracking, search results, previews, the editor, not found pages, filtered or sorted lists, and page 2 and later of a collection. Page 2 of the blog list stays indexable.

One address per page. Your free store address, a www. variant and every other domain of your store answer one permanent redirect to the same page on your primary address, path and query kept.

2. Redirects

A redirect sends one address to another. Two things write them:

  • Automatically. Change a product slug, a collection handle, a content page slug or a post slug and a 301 from the old address to the new one is written for you, and that object's SEO override moves across. Nothing you had linked to breaks.
  • By hand. For a page you removed, a campaign address you want to keep, or a move from a shop you came from.
Rule
fromPatha store path: starts with /, no spaces
toPatha store path, or an https URL to send people off-site
status301 (permanent, the default) or 302 (temporary)
Loopsa redirect that would send a shopper back where they started is refused
Limit500 a store

Trailing slashes and query strings never distinguish two redirects: /old-page/, /old-page and /old-page?utm_source=x all match the same row, and a store-path target keeps the query string it arrived with. Only the proof files of a search engine (§8) answer before redirects; after them the storefront checks redirects before anything else it serves, so a redirect can also shadow a page that still exists. Each row counts how many times it has been followed.

What the storefront answers on its own:

You ask forYour store answers
An address renamed once or several timesone 301 to the newest address
A redirect that leads to another redirectone 301 to the end of the chain (302 if any step is temporary)
/Products/Blue-Mug, //products//blue-mug, /products/blue-mug/one 301 to /products/blue-mug, query kept
/pages/Shipping404: a content page's handle keeps its case (/Pages/shipping still folds)
A product, collection or page you deleted in the last 90 days410 (gone)
A deleted post, a draft, an archived or hidden product or collection, an unknown address404

When you rename something, redirects that pointed at the old address, including ones you wrote, now point at the new one; their status and hit count are kept. Renaming back to an earlier address removes the automatic redirect away from it. A redirect you wrote away from that address is kept.

Media, feeds, sitemaps, account pages, order tracking and download links are never respelled.

Dashboard. Online store → Pages, under the page list.

Routes. GET /api/redirects, PUT /api/redirects with { fromPath, toPath, status? }, DELETE /api/redirects?id= or ?fromPath= (storefront:read / storefront:write).

Tools. list_redirects, set_redirect { fromPath, toPath, status? }, delete_redirect { id | fromPath }.

3. Posts

A post is a piece of writing that lives on your store. Same Markdown as content pages, same theme, same header and footer.

FieldLimit
sluglowercase words joined by hyphens, 100
title160
excerpt300; what the list, the feed and the description show
bodyMarkdown50,000
coverImageUrlan https URL, usually one your store already holds
author80
tags10 tags, 40 characters each
statusdraft or published

Only a published post is visible. Publishing stamps publishedAt once: unpublishing and republishing keeps the original date, so a post does not jump to the top of the feed because it was edited. Up to 500 posts a store.

Where they appear:

AddressWhat it is
/blogthe list, newest first, 12 a page (?page=2)
/blog/<slug>the post, with Article structured data
/blog/feed.xmlRSS 2.0, the 50 newest posts
/sitemap.xml/blog and every published post

Dashboard. Online store → Pages: the post list, a Markdown editor, a cover upload and a Published switch. Add /blog to your header or footer from the same screen to give readers a way in.

Routes. GET /api/posts (all, drafts included), GET /api/posts?id= or ?slug=, PUT /api/posts, DELETE /api/posts?id= (storefront:read / storefront:write).

Tools. list_posts, upsert_post, set_post_image { postId, url | dataBase64 + contentType } and delete_post.

4. Reading posts from your own front end

The storefront read API is public, cached and CORS-open, like the rest of it (headless.md):

EndpointAnswers
GET /api/storefront/posts{ posts: [{ slug, title, excerpt, coverImageUrl, author, tags, publishedAt, updatedAt, url }] }
GET /api/storefront/posts/<slug>{ post: { …, bodyHtml } }, the Markdown already rendered

Drafts are never returned: an unpublished slug is a 404, the same as an unknown one.

5. Events

Every change here is in the store's event log (events.md): post.created / post.updated / post.deleted, redirect.created / redirect.deleted (the resource id is the redirect id) and seo_override.created / seo_override.updated / seo_override.deleted, whose resource id is <ownerType>:<handle>. Subscribe to post.* to rebuild a cache when writing is published, or to redirect.* to mirror moves into a front end of your own.

6. Structured data

Every indexable page carries one block of structured data that search engines read for rich results:

PageWhat is written
HomeOrganization (name, logo, contact details, address and social links you entered) and WebSite with a search box that opens your store's /search
ProductProduct with its offers: the price in the product's currency with that currency's own decimals (two for dollars, none for yen), availability, every image, SKU and barcode when you entered them, the brand, and a breadcrumb
Collectiona breadcrumb and an item list of the products on that page, numbered on across pages; a filtered or sorted list carries the breadcrumb only
Pagea breadcrumb, and an FAQ when a section on the page holds questions you saved
PostArticle and a breadcrumb
Blog lista breadcrumb
  • Brand is the product's vendor, else your store's name.
  • Availability is in stock, out of stock, or back order when the product takes orders past zero. A gift card is always in stock.
  • Variants at different prices make a price range of up to 50 offers.
  • Breadcrumb of a product: Home, the first collection that lists it, the product.
  • FAQ also appears on the home page and product pages when a section placed there holds saved questions. Sample questions a section shows before you edit it do not count.

Cart, search and not found pages carry none. Ratings and reviews are not written today. The Reviews app loads its reviews in the shopper's browser after the page arrives, so the page itself has no reviews to describe, and your store never writes a rating it cannot show.

7. Sitemap and robots.txt

/sitemap.xml lists the addresses search engines should index, all on your primary address: the home page, /collections/all, active products, visible collections, published pages and posts, and /blog once a post is published. Drafts, archived products, hidden collections and anything whose override says noindex or names another canonical address are left out.

  • Up to 1,000 addresses it is one file. Beyond that /sitemap.xml is an index of parts: /sitemap-pages-1.xml (home, /collections/all, pages and /blog), /sitemap-collections-1.xml, /sitemap-products-1.xml and /sitemap-posts-1.xml, then -2 and on, 1,000 addresses each.
  • **lastmod** is when the thing last changed. For a product that is the time its content was last saved (created, saved, or archived or activated in bulk), or its latest recorded change in the last 90 days if that is later. A sale changes stock, not content: it is a recorded change, not a save.
  • Images: each product lists up to 20 of its pictures.

What a closed or hidden store answers:

Your storerobots.txtSitemap
Openthe lines belowevery address
Hidden from searchDisallow: / for every crawlerempty
Coming soonDisallow: / for every crawlerempty
PasswordDisallow: / for every crawlerthe home address only

Every sitemap file of a closed or hidden store carries a noindex header, and every part is empty. An open store's robots.txt:

User-agent: *
Allow: /
Disallow: /cart
Disallow: /checkout
Disallow: /account
Disallow: /search
Disallow: /orders/
Disallow: /email/unsubscribe
Disallow: /newsletter/
Disallow: /downloads/
Disallow: /l/
Disallow: /__fh/
Disallow: /api/storefront/orders
Disallow: /api/storefront/account
Disallow: /*?fh_edit=
Disallow: /*&fh_edit=
Disallow: /*?fh_preview=
Disallow: /*&fh_preview=
Disallow: /*?sort=
Disallow: /*&sort=
Disallow: /*?tag=
Disallow: /*&tag=
Disallow: /*?vendor=
Disallow: /*&vendor=
Disallow: /*?type=
Disallow: /*&type=
Disallow: /*?availability=
Disallow: /*&availability=
Disallow: /*?price
Disallow: /*&price
Disallow: /*?opt.
Disallow: /*&opt.

User-agent: GPTBot
User-agent: OAI-SearchBot
User-agent: ChatGPT-User
User-agent: ClaudeBot
User-agent: anthropic-ai
User-agent: PerplexityBot
User-agent: Google-Extended
User-agent: Applebot-Extended
User-agent: CCBot
User-agent: Bytespider
Allow: /
Disallow: /cart
Disallow: /checkout
Disallow: /account
Disallow: /search
Disallow: /orders/
Disallow: /email/unsubscribe
Disallow: /newsletter/
Disallow: /downloads/
Disallow: /l/
Disallow: /__fh/
Disallow: /api/storefront/orders
Disallow: /api/storefront/account
Disallow: /*?fh_edit=
Disallow: /*&fh_edit=
Disallow: /*?fh_preview=
Disallow: /*&fh_preview=
Disallow: /*?sort=
Disallow: /*&sort=
Disallow: /*?tag=
Disallow: /*&tag=
Disallow: /*?vendor=
Disallow: /*&vendor=
Disallow: /*?type=
Disallow: /*&type=
Disallow: /*?availability=
Disallow: /*&availability=
Disallow: /*?price
Disallow: /*&price
Disallow: /*?opt.
Disallow: /*&opt.

Sitemap: https://shop.example.com/sitemap.xml

shop.example.com stands for your primary address.

AI assistants

Let AI assistants read my store (Search & sharing, on by default) decides whether assistants such as ChatGPT and Claude may read your pages, quote them and link to them. On, robots.txt gets one more group naming the AI crawlers (GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, anthropic-ai, PerplexityBot, Google-Extended, Applebot-Extended, CCBot, Bytespider) with the same rules as everyone: your pages open, your cart, checkout, account and filtered views closed. The rules are repeated because a crawler named in its own group follows only that group. Off, that group says Disallow: / and /llms.txt answers "not found". Search engines are not affected either way: Googlebot and Bingbot keep the rules above. Google-Extended and Applebot-Extended do not fetch pages; they tell Google and Apple whether pages their search crawlers read may be used for their AI answers.

It is one switch on purpose: there is no separate setting for assistants that learn from pages and assistants that answer with them. A hidden or closed store refuses every crawler already. Agents change it with set_seo { aiAssistants: false }.

8. Search engines

When you connect a search engine, it asks for proof that the store is yours. Your store answers the proof file on your primary address, also while the store is closed, before any redirect. The ownership tag goes on your home page only, and never on the editor's or a preview's copy of it. Connecting is described in Search engines.

9. Health check

Your store checks itself for search problems and says how to fix each one. Nothing changes until you fix it.

CheckSeverity
The store is closed, or hidden from searchhigh
A page has no titlehigh
Redirects send visitors in a circlehigh
A page has no search descriptionmedium
The same title or description on several pagesmedium
A page has no main headingmedium
A product has no imagemedium
A link goes to a page that does not existmedium
A redirect leads to another redirectmedium
A title over 60 or under 15 characterslow
A description over 160 or under 70 characterslow
A page has several main headingslow
A product image has no descriptionlow
A product description under 50 wordslow
A product image over 500 KBlow
A link goes through a redirectlow

Links are checked in your pages, posts and menus. Up to 60 pages are checked at a time, and a report lists up to 200 findings, the most serious first. A closed store is checked on its data only; its pages are checked once it is open.

Dashboard. Online Store → Search & sharing → Health: each finding has a Fix link to the screen that fixes it.

Route. GET /api/seo-audit (storefront:read).

Tool. get_seo_audit { limit?, severity? }: limit from 1 to 200 (default 50), severity high, medium or low. Read-only.

Insights. For what to do next, get_seo_insights and the dashboard's Online Store → SEO insights screen propose topics to write about, titles to improve, pages that compete for the same search, pages to remove and whether assistants can read the store, each with its evidence. Titles and pages to remove need a connected search engine. Both only propose: you apply a step with set_seo, set_redirect, upsert_post or set_content_pages.

See also

  • agents.md: the twelve tools here, their scopes, and what still needs a publish.
  • analytics.md: your store's search performance, and how it shows which titles to rewrite.
  • product-kinds.md: a digital or service product's page is indexed like any other.
  • headless.md: reading posts, and following the redirect table, from a front end of your own.