"Canonicals are wrong."
"Product pages output a canonical pointing to the HTTP version of the URL. They should point to HTTPS. 1,842 URLs affected, three examples below, here's the HTML."
The first gets a reply asking what you mean. The second gets fixed. The difference isn't how technical you are. It's whether a developer can pick up the ticket, reproduce the problem, make the change, and know when they're done, without coming back to ask.
What Every Ticket Needs to Answer
If a developer can answer all seven from the ticket alone, it's ready.
Describe the Behavior, Not the SEO Concept
SEO terms describe effects. Developers fix behavior. Translate one into the other.
| Instead of | Write |
|---|---|
| Google can't crawl these pages | Internal links on category pages point to URLs that return 404 |
| Fix redirects | /old-page returns 302. It should return 301 to /new-page |
| The page isn't indexable | Product URLs send an X-Robots-Tag: noindex response header |
| Google doesn't see the content | The product description is missing from the server HTML and only appears after the client fetches /api/product |
| Canonicals are wrong | The product template outputs http:// canonicals on https:// pages |
The right-hand column names something a developer can find in code: a template, a header, a status code, an API call.
Give Examples and a Count
Never send a sitewide issue without URLs. Include three representative examples, and say why you picked them:
1,842 of 14,620 crawled URLs are affected, all on the product detail template. These three are from different categories and all reproduce the issue: /products/widget-a, /products/garden/hose-b, /products/kitchen/pan-c
- Pick examples from different sectionsIt tells the developer this is a template problem, not a one-off.
- Attach the full list as a CSVDon't paste thousands of URLs into the ticket body.
- Always give the count"Several pages" could mean four or 40,000, and the right fix is different for each.
Show Expected vs Actual
This is the part developers read first. Make it impossible to misread:
<link rel="canonical" href="https://example.com/products/widget-a">
<link rel="canonical" href="http://example.com/products/widget-a">
Bring the Right Kind of Evidence
Smallest proving snippet
Not the whole page source. Say whether it came from raw HTML or the rendered DOM.
The response itself
Status codes, redirects, and headers never appear in the HTML.
Context only
Useful for a CMS field or layout issue. Never proof of what's in the code.
HTML evidence
If the issue is a missing element, show the section where it should be. Here, the head has no canonical at all:
<head>
<title>Widget A | Example</title>
<meta name="description" content="...">
</head>
If the site renders with JavaScript, say whether the snippet came from the raw HTML or the rendered DOM. They can differ, and a developer checking the other one will think you're wrong.
HTTP evidence
A curl command is ideal, because the developer can run it and get the same result:
curl -I https://example.com/old-page
HTTP/1.1 302 Found
Location: https://example.com/new-page
A noindex sent as an X-Robots-Tag response header never shows up in View Source. A developer looking at the HTML will see nothing wrong. Show the header.
Explain Severity in One Line
"High priority" with no reason gets deprioritized. Give the reason:
Severity: High. 4,200 product URLs that should rank send noindex. Those pages earned about 18,000 Search Console clicks last month before the change.
A number like that does more to get a ticket picked up than any severity label. Scoring severity across a whole audit is covered in our guide to SEO audit prioritization.
Write Reproduction Steps
- Open the URLhttps://example.com/products/widget-a
- View the page sourceNot Inspect, which shows the live DOM.
- Search for rel="canonical"Use Ctrl+F in the source view.
- See the problemThe href starts with
http://.
Suggest the Outcome, Not the Code
You probably don't know how the canonical is generated. Describe the result and let the developer choose the implementation:
"Change line 147."
"The canonical should be the HTTPS URL of the page itself, generated in the product template."
Link the relevant Google Search Central documentation when it helps. Developers are more comfortable changing behavior when the requirement comes from a primary source.
Write Acceptance Criteria
Without them, a ticket can be closed with the problem half fixed. The Given/When/Then format many teams already use works well:
Given any indexable product page
When the page is requested
Then the HTML head contains exactly one rel="canonical"
And its href is the page's own HTTPS URL without tracking parameters
Then add the part most SEO tickets forget, a list of what must not change:
Canonical output on category and blog templates, and noindex on /search/ and /cart/. This is the cheapest regression protection there is.
Say How It Will Be Verified
Staging often differs from production in caching, CDN rules, and environment settings, so a fix that passes on staging can still fail live. For the full process, see our guide to SEO testing before and after deployment.
Split Findings by Root Cause
"5,000 URLs with indexing issues" might really be three unrelated problems:
- Product pages wrongly sent noindexLives in the product template.
- Category pages blocked in robots.txtLives in server config.
- Redirected URLs still in the XML sitemapLives in the sitemap generator.
One ticket per root cause gets done. One ticket per audit category gets stuck. When you only suspect the cause, say so:
Suspected cause: titles appear to be built from the category name instead of the product name. Evidence: all 1,200 duplicates share their category's name.
Keeping evidence and assumptions separate builds trust. A developer who finds that one of your "facts" was a guess will question everything else in the ticket.
Not Everything Is a Developer Ticket
Weak title wording, thin descriptions, vague anchor text, and missing copy usually belong with content editors. Sending them to engineering wastes sprint time and makes SEO tickets look like noise. Save the developer queue for problems that need code.
A Complete Ticket
| Field | Content |
|---|---|
| Title | Product pages output HTTP canonical instead of HTTPS |
| Scope | Product detail template. 1,842 of 14,620 crawled URLs. |
| Examples | /products/widget-a, /products/garden/hose-b, /products/kitchen/pan-c (full list as CSV) |
| Expected | <link rel="canonical" href="https://example.com/products/widget-a"> |
| Actual | <link rel="canonical" href="http://example.com/products/widget-a"> (raw HTML) |
| Severity | High. Canonicals point to URLs that redirect, so Google gets conflicting signals. These pages drive about 40% of organic clicks. |
| Reproduce | Open any example, view source, search for rel="canonical". |
| Suggested fix | Build the canonical from the page's HTTPS URL in the product template. |
| Acceptance | Given any indexable product page, when requested, then exactly one canonical with the page's own HTTPS URL. |
| Must not change | Category and blog canonicals. Noindex on /search/ and /cart/. |
| Verify | Examples on staging, then production. Re-crawl the template, expect 0 affected URLs and 0 duplicate canonicals. |
Template You Can Copy
Title:
Scope (template / section / URL count):
Examples (3, with reason chosen):
Expected:
Actual:
Evidence (HTML or HTTP, raw or rendered):
Severity and reason:
Reproduction steps:
Suggested outcome:
Acceptance criteria:
Must not change:
Verification:
Owner:
From Audit to Ticket in SiteAuditLint
Most of what goes into a good ticket is already in the audit. In SiteAuditLint, every issue comes with its severity, why it matters, how to fix it, and the exact affected URLs, which covers scope, examples, and much of the evidence. The Linear SEO Tickets integration turns an issue straight into a Linear ticket, so you start with the facts filled in and add expected behavior, acceptance criteria, and the "must not change" list on top.
After the fix ships, re-crawl and use audit comparison to show the affected count dropping to zero.