A Practical Technical SEO Checklist for Agencies That Need to Ship
By Seth Black · Published
Most “ultimate technical SEO checklists” run 200 bullets and promise this one is different. An agency opens the doc, knocks out 30 items, gets pulled into a client call about why a blog post isn’t ranking, and the checklist dies in a Drive folder next to the last one.
You don’t need a longer list. You need a shorter sequence you can ship in a week. The problem with those checklists isn’t the bullets. Nobody scoped the work.
Here’s the three-pass audit I keep coming back to. Each pass has one job and a time box, because “however long it takes” is how audits turn into retainer black holes. Every item ends in something a programmer can act on: a template to change, a header to fix, or a rule to write.
Pass 1: Crawl, indexation, and the obvious blockers
Goal: figure out what Google can and can’t see. Budget: 2 to 4 hours for a mid-size site.
This is the stuff that makes the rest of the audit pointless if it’s broken.
- robots.txt. Is it blocking sections, JavaScript, or CSS it shouldn’t? A rule that blocks
/static/or/_next/can stop Google from rendering the whole site. - Meta robots and
X-Robots-Tag. Anoindexin an HTTP header overrides everything in your HTML, and almost nobody checks headers. Staging flags leaking into production are the classic version. - Robots conflicts. A page blocked in robots.txt can’t show Google its
noindexor its canonical. A homepage link to anoindexpage is a mixed signal. - Status codes on internal links. Dump every internal link with its final status. 302s where you meant 301s, chains longer than one hop, 404s in the main navigation.
- Canonicals. Pointing at redirects, 404s,
noindexpages, staging hostnames, or chains. - XML sitemaps. Every URL listed should return 200, be canonical, and be indexable. Diff the sitemap against the crawl. The delta is usually embarrassing.
- hreflang. Missing return links, invalid codes, and conflicts with canonicals, especially if the site was replatformed recently.
- Indexation sanity. Search Console’s indexed count, your sitemap count, and your crawl count should roughly agree. When they don’t, something is filtering pages out or generating junk.
If a client has 40% of their money pages carrying noindex because someone forgot a staging flag, stop the audit and write that ticket. Everything else can wait until that one line changes. For the deeper cleanup on this pass, see fixing crawl errors and fixing broken canonical tags.
Pass 2: Templates and internal linking
Goal: stop auditing pages and start auditing patterns. Budget: 3 to 5 hours.
Most large sites have 8 to 12 templates: product, category, article, author, location, and so on. A broken canonical on the product template isn’t one issue. It’s 14,000 issues fixed by one programmer changing one component.
- Group URLs by template. Use path patterns. Every finding from Pass 1 should be re-counted per template.
- Titles and meta descriptions per template. Missing, duplicated, and near-duplicated. Templated descriptions that differ by one variable read as duplicates, and near-duplicate meta descriptions need similarity checks, not string matching.
- Structured data per template. Run representative pages through Google’s Rich Results Test and a schema validator. Check that
Producthas a real price, thatArticlehas a realdatePublished, and that the markup matches what’s visible. - Internal link graph. Which templates link to which? Where do orphans live? Are important pages more than four clicks from the homepage? Do category pages pass authority down to products, or leak it into facet URLs?
- Parameter and facet URLs. On ecommerce sites, this is usually where the index bloat comes from.
Walk out of this pass with tickets a programmer can ship, written as “change this template,” not a CSV that gets opened once and archived.
Pass 3: Performance and JavaScript
Goal: catch what non-rendering crawlers and homepage-only speed tests miss. Budget: 2 to 4 hours.
- Raw HTML versus rendered HTML. Compare the
curlresponse to the rendered DOM on each template. Titles, canonicals, H1s, internal links, and structured data that only exist after hydration depend on Google finishing its render. If the site leans on client-side rendering, this is the pass where most audits quietly fail. - Links that aren’t links. Navigation built on click handlers instead of
<a href>. - Render-blocking resources. Scripts and stylesheets in the critical path that could be deferred, async, or split.
- Core Web Vitals on real templates. Not the homepage. Use field data from CrUX or Search Console for the templates that carry traffic, then find the cause per template: unsized images, a late LCP image, third-party scripts, a tag manager container nobody has reviewed as a whole.
Hand the programmers a list of broken components, not 4,000 URLs that trace back to the same template.
Where BSA fits
The manual version of this process got old fast, which is the short version of why I built Black SEO Analyzer. One crawl covers most of Pass 1 and a lot of Passes 2 and 3: it renders pages in headless Chrome, runs 16 analysis modules across 300+ issue types, and stores every crawl in a local SQLite database, so you can regenerate reports or compare against last quarter without crawling again. The HTML reports use templates you can customize, so the client sees your branding. The Agency License is a one-time $1999 with lifetime updates, which beats per-seat pricing once you’re past a handful of clients.
Three passes, defined hours, and tickets at the end. That’s the whole thing.
Running this across multiple clients? Try BSA free for 14 days with every feature and no page limit, then see pricing for the one-time Agency License.
-Sethers