How to Report Technical SEO Issues to Developers

AI OVERVIEW

A good SEO ticket names the template, gives a count and three URLs, shows expected vs actual code, and says what must not change.

An audit finding

"Canonicals are wrong."

A ticket

"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

WhatOne sentence
→
WhereTemplate and URL count
→
ExpectedWhat should happen
→
ReproduceSee it yourself
EvidenceHTML or HTTP
→
SeverityHow bad, and why
→
DoneHow we know it's fixed

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 ofWrite
Google can't crawl these pagesInternal 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 indexableProduct URLs send an X-Robots-Tag: noindex response header
Google doesn't see the contentThe product description is missing from the server HTML and only appears after the client fetches /api/product
Canonicals are wrongThe 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:

Expected

<link rel="canonical" href="https://example.com/products/widget-a">

Actual

<link rel="canonical" href="http://example.com/products/widget-a">

Bring the Right Kind of Evidence

HTML

Smallest proving snippet

Not the whole page source. Say whether it came from raw HTML or the rendered DOM.

HTTP

The response itself

Status codes, redirects, and headers never appear in the HTML.

Screenshot

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
Why headers matter most

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:

A guess

"Change line 147."

A requirement

"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:

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

StagingCheck the 3 examples
→
ProductionCheck them again live
→
Re-crawlAffected count is zero
→
Side effectsNo URL has two canonicals

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

FieldContent
TitleProduct pages output HTTP canonical instead of HTTPS
ScopeProduct 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)
SeverityHigh. Canonicals point to URLs that redirect, so Google gets conflicting signals. These pages drive about 40% of organic clicks.
ReproduceOpen any example, view source, search for rel="canonical".
Suggested fixBuild the canonical from the page's HTTPS URL in the product template.
AcceptanceGiven any indexable product page, when requested, then exactly one canonical with the page's own HTTPS URL.
Must not changeCategory and blog canonicals. Noindex on /search/ and /cart/.
VerifyExamples 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.

[Add screenshot here: a SiteAuditLint issue turned into a Linear ticket, showing which fields come pre-filled.]
A finding says what's wrong. A ticket says where, what correct looks like, and how to prove it's fixed.