Fifteen minutes, four decisions. A physiotherapy clinic moved its site last week and one service page has disappeared from search while an old short link lands somewhere odd. You get the live responses, one row of the migration's URL map, and three lines of template — and you get to find out why auditing the template instead of the response misses the fault entirely.
Technical SEO Lab
A fixture with a canonical pointing at staging and a redirect landing on the homepage. Find both from rendered responses, pick the first safe fix, verify it.
The interactive version could not be loaded. The complete lab, including every answer, is on this page below.
Declared sample data
Every response below is a fixture written for this lab. harbourline.example and staging.harbourline.example do not exist; nothing was fetched from a real site. The fixture files are public downloads so you can run your own checks against them.
Evidence
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Physiotherapy in Harbourline | Harbourline Physio</title>
<meta name="description" content="Hands-on physiotherapy for backs, knees and sports injuries at three Harbourline clinics. Same-week appointments.">
<link rel="canonical" href="https://staging.harbourline.example/services/physiotherapy">
<meta name="robots" content="index,follow">
<script type="application/ld+json">{"@context":"https://schema.org","@type":"MedicalBusiness","name":"Harbourline Physio","url":"https://harbourline.example/"}</script>
</head>> GET /physio HTTP/1.1 > Host: harbourline.example < HTTP/1.1 301 Moved Permanently < Location: https://harbourline.example/ > GET / HTTP/1.1 > Host: harbourline.example < HTTP/1.1 200 OK < Content-Type: text/html; charset=utf-8 Hops: 1 · Final URL: https://harbourline.example/ · Final status: 200
| source_url | target_url | disposition | expected_status |
|---|---|---|---|
| https://harbourline.example/physio | https://harbourline.example/services/physiotherapy | MOVE | 301 |
<link rel="canonical" href="{{ settings.site_origin }}{{ request.path }}">
<!-- settings.site_origin is set in the platform admin, not in this file -->Steps
Step 1 — What is wrong with the physiotherapy page?
Read the response head as the server returned it. The template is included so you can see where the value comes from — but audit the response, not the template.
Evidence: GET https://harbourline.example/services/physiotherapy — response head (200), layouts/theme.liquid, lines 12–14 (repository, for reference)
Which statement is correct?
- The canonical tag is missing, so search engines cannot tell which URL is preferred.
- The canonical points at the staging host, so it tells search engines the preferred copy of this page lives on a site that should not be indexed.
- The page is set to noindex, which is why it dropped out.
- Nothing is wrong with the head; the drop must be a content problem.
Answer and explanation
The canonical points at the staging host, so it tells search engines the preferred copy of this page lives on a site that should not be indexed.
The canonical is present and well-formed, but its host is staging.harbourline.example. A canonical is a claim that another URL is the preferred version of this content; when that URL is the staging copy, the production page is telling search engines to prefer a copy that is (or should be) blocked. The robots meta is index,follow — it is not the cause. This is exactly the fault that reading the template misses: the template is correct, and the value of settings.site_origin was never changed after cutover.
Step 2 — What is wrong with the /physio short link?
Compare the redirect trace with the row from the migration's own URL map.
Evidence: GET https://harbourline.example/physio — redirect trace, From the migration's url-map.csv (row 41)
Which statement is correct?
- It is a redirect chain — too many hops.
- It loops.
- It redirects in one hop with a 301, but to the homepage instead of the mapped destination — the visitor loses the page they were promised, and the search engine treats it as a soft 404.
- It is a single 301 that ends in a 200, so it is correct.
Answer and explanation
It redirects in one hop with a 301, but to the homepage instead of the mapped destination — the visitor loses the page they were promised, and the search engine treats it as a soft 404.
Status and hop count are fine; the destination is not. The map says /physio should land on /services/physiotherapy. A redirect to the homepage discards the intent of the link and, in bulk, is what Google's documentation on site moves describes as treated like a soft 404. A checker that only asserts 'one hop, 301, final 200' passes this. A checker must compare the final URL with the mapped destination.
Step 3 — What do you fix first, and how?
You have read-only access and a change window later today. Choose the first safe change.
Evidence: layouts/theme.liquid, lines 12–14 (repository, for reference), GET https://harbourline.example/services/physiotherapy — response head (200)
Which is the right first move?
- Change the one platform setting (site_origin) to the production host on the staging copy, verify the rendered canonical there, then release — because every page on the site carries the same wrong host.
- Hard-code the correct canonical into the physiotherapy page's template so at least that page is right.
- Resubmit the sitemap in Search Console so Google re-reads the page.
- Fix the /physio redirect first; it is the one the owner noticed.
Answer and explanation
Change the one platform setting (site_origin) to the production host on the staging copy, verify the rendered canonical there, then release — because every page on the site carries the same wrong host.
The evidence says the canonical is built from one setting, so the fault is site-wide, not one page — every page is telling search engines to prefer staging. One setting change fixes all of them, is trivially reversible, and can be verified on the staging copy before release. The redirect fix is the second change in the same window; it is one row in the redirect table.
Step 4 — Which evidence proves it is fixed?
The change was released. Below is the after-state. Decide whether it is evidence, and of what.
Evidence: After: GET https://harbourline.example/services/physiotherapy — response head (200), After: GET https://harbourline.example/physio — redirect trace
What does the after-state establish?
- Both faults are fixed on the live origin: the canonical is self-referencing on the production host, and /physio lands on the mapped destination in one 301 hop.
- The template was fixed; the live page still needs to be checked.
- The page will rank again.
Answer and explanation
Both faults are fixed on the live origin: the canonical is self-referencing on the production host, and /physio lands on the mapped destination in one 301 hop.
Both after-state captures are live responses, so they verify the change on the real origin — not in the template, not on staging. Note what they do not prove: that Google has re-crawled, or that any ranking will return. That is what monitoring over the next weeks is for.
The corrected version
<link rel="canonical" href="https://harbourline.example/services/physiotherapy"> <meta name="robots" content="index,follow">
> GET /physio HTTP/1.1 < HTTP/1.1 301 Moved Permanently < Location: https://harbourline.example/services/physiotherapy > GET /services/physiotherapy HTTP/1.1 < HTTP/1.1 200 OK Hops: 1 · Final URL matches url-map.csv row 41 · verified
What you did here — reading the rendered response, comparing a redirect's destination against a map instead of trusting its status, and choosing the smallest reversible change — is the whole discipline. The scoped audit prompt in the guide writes those rules down so an agent follows them on your pages.
Walkthrough
Four screenshots of this lab, taken from the published page: the start, a deliberately wrong answer, the matching answer, and the corrected version. Every screen is described in the image text.

1. Step 1: audit the response, not the template. 
2. A wrong answer, explained from the evidence. 
3. The matching answer unlocks the next step. 
4. The corrected version: both faults fixed on the live origin.
Take it to your own site
- How to run a technical SEO audit with Claude Code — the guide this lab is drawn from
- Build a scoped audit prompt for your own pages
- Technical SEO checklist
- Claude Code SEO & Website Audit Toolkit — The audit prompts and the redirect checker in the toolkit are the production versions of what you just did by hand.