In short: Canvas lets Sidekick edit a copy of your Shopify theme code from a chat. In a test with a 650-item Load more list, three precise prompts produced code that loaded nothing and three vague prompts worked, so check the result in a browser, not in Sidekick’s reply.
What is Canvas, and what do you need to use it?
Canvas is a design workspace in the Shopify admin. You describe a change to Sidekick, Shopify's built-in assistant, and it edits the files of a theme. Shopify announced it on 1 October 2026 and says merchants are not editing a static preview but a render of the real code behind the store[1]. It is early access: Shopify's help pages say it is "available only to certain stores"[2].
The requirements and limits that matter to a developer, from Shopify's own pages[3][4][5]:
- Canvas works on desktop only, on plans that include theme customisation, and only with themes made by Shopify or custom themes. Third-party Theme Store themes are not supported.
- Staff need the Online store > Themes > Edit code permission to open it.
- You cannot add or configure app blocks or app embeds. Per-market customisation is not available, a Canvas theme cannot be edited through a rollout, and translations go through the Translate & Adapt app.
- A theme you create or edit in Canvas opens only in Canvas, not in the theme editor, and it no longer receives theme updates.
- You cannot add a new block by hand. You ask Sidekick to add it.
- "Duplicate in Canvas" makes a separate copy. Changes to the copy do not reach the original. Publishing a Canvas theme replaces your live theme.
- When Sidekick makes a change, your undo history is cleared. To reverse its work you ask it to change things back or restore an earlier version from the theme history.
Plan around that last point: use Canvas on a copy, never on the only copy.
What did we ask Sidekick to build?
The test ran on a development store with the plainest possible list: a home page showing 650 metaobject entries with paginate by 50, a for loop and Shopify's standard page links. No JavaScript. A for loop stops after 50 iterations and paginate allows at most 250 items per page, so a long list needs paging in the page itself[6]. Our guide to the 50-entry loop limit and paginate covers that limit in detail.
The task was to load more of the list into the same page, without a full reload, and keep the Back button working. Every run started from a fresh Canvas copy of the same theme and a new chat. We wrote two prompts and ran each three times.
The precise prompt:
On the home page the list shows 650 entries from the metaobject definition lab_item, 50 per page, with the standard page links below. Add a Load more button below the list that appends the next 50 items to the same list without a full page reload. Requirements: use paginate with a page size of 50 and never above 250; never loop over more than 50 items in one for loop; the first page must be rendered on the server and work without JavaScript, with a normal next page link as the fallback; keep the address bar in step with what is loaded (history API) so that after opening another page and pressing the back button the same items are shown at the same scroll position; no duplicate items; the button must be a real button element, focus must move to the first new item, and an aria-live region must announce how many items were added. Do not change other templates or theme settings.
The vague prompt:
Make the list on the home page load more items when people want to see more, without paging.
What happened with the precise prompt?
Each precise run took about five minutes. Compared with the starting theme, each pull contained changes to the snippet, script, stylesheet and language file, plus an autogenerated settings-file comment and a password layout that were not in the starting theme. Each one passed Shopify's Theme Check with no offences[7]. Each reply described a working feature, and each also said that Sidekick could not click in the preview and asked us to try it.
We tried it. In all three runs the button added nothing.
| Run | Items after three clicks | What the status message said | Browser history |
|---|---|---|---|
| Precise 1 | 50 | "0 items added" | unchanged |
| Precise 2 | 50 | "0 items added" | unchanged |
| Precise 3 | 50 | "0 items added" | three new entries for three clicks that added nothing |

Before you try any of this: the snippets in this article only read from a storefront page you already have open, but Canvas edits real theme code. Work on a duplicate, do not publish a theme you have not tested, and make every change at your own risk. iLogr cannot see your store and accepts no responsibility for damage, data loss or downtime.
The cause was the same in all three. Each script asked for the next page with a hard-coded ?page=2. Shopify names that parameter page by default, but adds a unique key when the list comes from a setting or a metafield list[8]. In this test the metaobject list used a keyed name, page_f77c5841, and ?page=2 was ignored: the server returned page 1 again. On a list that uses the default name, the same script may well have worked; we did not test one. The scripts then dropped those items as duplicates and announced that none were added. Reading the first item of page 2 shows it:
const firstItem = async (query) => {
const html = await (await fetch('/?' + query)).text();
return new DOMParser().parseFromString(html, 'text/html').querySelector('#items li').textContent.trim();
};
({ plain: await firstItem('page=2'), keyed: await firstItem('page_f77c5841=2') })
// { plain: "Item 0001", keyed: "Item 0051" }
The precise-run replies said that clicking remained untested. Static checks cannot see this kind of fault, which is why the precise runs passed lint and still failed.
What happened with the vague prompt?
The vague runs took between two and five minutes, and all three worked. Each delivered 650 items in the right order, with no duplicates, after twelve loads. Focus moved to the first new item. A rapid triple click loaded one extra set of 50, not three. They read the next page address from the fetched page, so the keyed parameter was never an issue.
What the vague runs left out is what the vague prompt did not ask for:
- The numbered page links and the Previous link disappeared, so crawlers see one chain of Next links and shoppers cannot jump ahead.
- The address bar never changes and the scripts save no history state. By their code, reloading or sharing the URL starts with 50 items. Our Back test was inconclusive.
- In one run the hidden announcement said "More items loaded" every time, with no count, and repeated identical text is often not re-announced by screen readers. We did not test with a screen reader.
- One reply said the list needs 13 clicks. It needs 12, because the first 50 are already there.
We cannot prove why the precise prompt did worse. It asked for URL handling, which the vague prompt did not, and URL handling is where the hard-coded parameter appeared.
Can Sidekick fix its own bug?
Yes, when you describe the symptom. In a fresh chat on one of the broken copies, we wrote: "I tested the Load more button in the preview. When I click it the list stays at 50 items and the status message says 0 items added. Please fix it." In about two minutes Sidekick named the cause, a wrong page parameter, and changed two lines: it wrote paginate.page_param into a data attribute on the page and read it in the script. It then said, again, that it could not click and asked us to confirm.
We confirmed. Three rapid clicks loaded one extra set of 50, two more clicks brought the list to 200 unique items in order, and the status line counted pages one to four of 13. After opening another page and pressing Back, all 200 items returned and the first visible item, its position and the scroll offset matched what we had before leaving.
How should you check what Sidekick wrote?

- Read the diff. In our test,
shopify theme pulldownloaded a Canvas copy without trouble (Shopify CLI 4.9.4)[9], although Shopify's help pages say you cannot download the theme files of a theme edited in Canvas[3]. Check which applies to your store. Confirm only the files you expected changed, and that other templates and the settings file did not. - Run Theme Check, and do not trust it. A clean result passed in all six runs, including the three that did not work[7].
- Request page 2 yourself. Use the parameter name the script uses and the one in the page links. If the script's URL returns page 1 but the next-page link returns page 2, the script uses the wrong URL. The snippet above does this.
- Click it. Run this before and after clicking Load more by hand, once loading has finished. Compare the counts and read the announcements. It assumes unique item titles.
(() => {
const names = [...document.querySelector('#items').children]
.map((li) => li.textContent.trim());
return {
count: names.length,
duplicates: names.length - new Set(names).size,
announcements: [...document.querySelectorAll('[aria-live]')]
.map((el) => el.textContent.trim())
};
})()
- Test Back. Load a few times, scroll, open another page, press Back. The same items and the same first visible item should return.
- Read the server HTML without JavaScript. View the source or fetch the page. It should hold the first 50 items and a real link to the next page. Crawlers and slow connections see that, not the script's result.
- Test the keyboard and a screen reader. Focus should land on the first new item and each announcement should differ.
Where does Canvas fit for a developer?
For a first draft on a copy, it was quick and its code passed Theme Check. Its limits are plain: the precise-run replies left interaction testing to the reader; in our six runs a precise brief did not make it more accurate than a loose one; and everything you build in Canvas leaves the update path of your theme.
Themes created in Canvas contain two context files, AGENTS.md and DESIGN.md, which Sidekick reads before changing the theme[10]. Shopify warns that agents follow such rules "most of the time"[10]. The copy we pulled had neither file, because it was a duplicate of an ordinary theme. We did not test whether a rule about reading paginate.page_param would have prevented the failure.
For a hand-built version of the same 650-item task, using the Liquid partial tag that is still a developer preview, see our guide to load more and infinite scroll with partial.
References
Numbers in square brackets in the text link to these sources.
- Shopify, "Introducing Canvas: Opening the aperture on online store design" (opens in a new tab).Used for: the launch, real theme code, and how Sidekick works in Canvas.
- Shopify Help Center, "Canvas" (opens in a new tab).Used for: early access and availability to certain stores.
- Shopify Help Center, "Requirements and considerations for using Canvas" (opens in a new tab).Used for: requirements, limits, theme updates and file download.
- Shopify Help Center, "Creating and customizing themes in Canvas" (opens in a new tab).Used for: duplicating, publishing, undo history and version history.
- Shopify Changelog, "Design a fully bespoke store with Canvas" (opens in a new tab).Used for: the launch limits for themes, Markets, translations and app blocks.
- Shopify.dev, Liquid tag "paginate" (opens in a new tab).Used for: the 50-iteration loop limit and the page size of 1 to 250.
- Shopify.dev, Shopify CLI "theme check" (opens in a new tab).Used for: what Theme Check analyses.
- Shopify.dev, Liquid object "paginate" (opens in a new tab).Used for: the default page parameter and the unique key for lists.
- Shopify.dev, Shopify CLI "theme pull" (opens in a new tab).Used for: downloading theme files to a local folder.
- Shopify.dev, "AGENTS.md" for themes (opens in a new tab).Used for: context files Sidekick reads in Canvas, and the non-determinism warning.