Sample deliverable
Technical SEO Audit Report
What this document is. Pacific Coffee Roasters is a demo store I built myself and deliberately broke, so I could demonstrate the audit method on a site with real faults. Every number below came out of my crawler — nothing is estimated. The raw JSON is part of the deliverable, so you or your developer can recompute any figure in this report.
Technical health score
62/100
6 weighted dimensions
Pages crawled
2
2 dead links found
Homepage body copy
89 words
target is 600+
Total image weight
488 KB
target under 150
Images missing alt
2/2
100% missing
1. Executive summary
Eleven issues found. Three of them actively prevent this site from ranking. In plain terms:
- Two navigation links are dead.
/espressoand/wholesaleboth return 404. A crawler that follows the main menu hits a wall before it ever reaches a product page. - The homepage has 89 words of body copy, and those words are filler ("good coffee, very good, we care about coffee"). Google cannot tell what this page sells.
- The hero image is 464 KB and has no alt attribute. It slows mobile loading and throws away image search traffic at the same time.
If you only fix three things: repair the dead links, rewrite the homepage to 600+ words around one target keyword, then compress the images and add alt text. Those three account for roughly 70% of the measurable loss here.
2. How the score is calculated
Six dimensions, each scored out of 100 then weighted. You can recompute this yourself.
| Dimension | Weight | Score | What drove it |
|---|---|---|---|
| Crawlability and links | 25% | 55 | 2 dead links in primary navigation |
| Content depth | 20% | 50 | 89 words on homepage, 9 words on inner page |
| Title and meta description | 15% | 70 | Inner page title is 5 characters, zero description |
| Images | 15% | 60 | 464 KB hero, 100% missing alt |
| Mobile and canonicals | 15% | 80 | Inner page lacks viewport, no canonical sitewide |
| Structured data and JS rendering | 10% | 65 | No JSON-LD, content depends on document.write |
55×0.25 + 50×0.20 + 70×0.15 + 60×0.15 + 80×0.15 + 65×0.10 = 61.75, rounded to 62.
3. Issue list, ranked by impact
| # | Severity | Issue | Measured evidence | Recommended fix |
|---|---|---|---|---|
| 1 | Critical | Dead links in primary navigation | /espresso → 404/wholesale → 404 | Create the pages, or remove them from nav and 301 to the closest relevant page. Run a link check before every deploy. |
| 2 | Critical | Homepage copy is too thin and contains no substance | word_count = 89target keyword appears 0 times | Rewrite to 600–900 words: product line, origin, roast method, shipping, wholesale terms. Each section answers one real search intent. |
| 3 | Critical | No image on the site has alt text | imgs_total = 2imgs_no_alt = 2 | Add descriptive alt to every content image, using the keyword naturally. Decorative images get alt="". |
| 4 | High | Hero image is oversized, hurting mobile LCP | Banner-Final-FINAL-2.jpg464 KB (recommended under 120) | Convert to WebP and resize to actual display width. Expect 45–70 KB. |
| 5 | High | Inner page title is 5 characters and meaningless | title = "Beans" (len 5) | Rewrite as "Buy Single-Origin Coffee Beans | Pacific Coffee Roasters". |
| 6 | High | Inner page has no meta description at all | meta_desc_len = 0 | Write 140–160 characters including a call to action. |
| 7 | Medium | Inner page has no viewport tag | beans.html: has_viewport = false | Add the viewport meta to the shared template so all pages inherit it. |
| 8 | Medium | No canonical tags anywhere | has_canonical = false on 2 of 2 pages | Add a self-referencing canonical to every page. |
| 9 | Medium | No Open Graph tags, so social shares render bare | has_og = false | Add og:title, og:description, og:image. |
| 10 | Medium | No structured data of any kind | has_ldjson = false | Add LocalBusiness and Product JSON-LD to compete for rich results. |
| 11 | Medium | Content rendering depends on JavaScript | uses_noscript_gate = trueinline script 0.1 KB via document.write | Render core content server-side and drop document.write. |
4. Page-by-page detail
| Page | Status | HTML | Title length | Desc length | H1 / H2 | Body words | Missing alt | Viewport / Canonical |
|---|---|---|---|---|---|---|---|---|
| /index.html | 200 | 1.3 KB | 49 ok | 60 warn | 1 / 3 | 89 fail | 2/2 fail | ok / fail |
| /beans.html | 200 | 0.3 KB | 5 fail | 0 fail | 1 / 0 | 9 fail | 0/0 | fail / fail |
5. Raw evidence
Actual HTML fragments from the crawl. Open the page yourself and you will find the same tags.
Evidence 1 — hero image has no alt and weighs 464 KB
<img src="/assets/Banner-Final-FINAL-2.jpg" style="width:100%">
→ alt attribute absent. Measured: 464113 bytes.
Evidence 2 — navigation points at pages that do not exist
<a href="/espresso">Espresso Blends</a>
<a href="/wholesale">Wholesale For Cafes</a>
→ both targets returned 404 during the crawl.
Evidence 3 — body copy is filler, no indexable substance
<p>Quality coffee. Great service. Good prices. We care about coffee.
Our coffee is very good. You will like our coffee a lot...</p>
→ total indexable body text on the page: 89 words.
Evidence 4 — core content depends on JavaScript
<noscript>Please enable JavaScript.</noscript>
<script>document.write("<p>Today is " + new Date().toDateString() + "</p>");</script>
6. 30-day fix plan
Week 1 — stop the bleeding
- Fix both dead links (create or 301)
- Add alt text to every image
- Convert the hero image to WebP
- Add viewport and canonical to the template
Weeks 2–3 — build content
- Rewrite the homepage to 600+ words around one primary keyword and three long-tail variants
- Rewrite every inner page title and description
- Add LocalBusiness and Product JSON-LD
- Submit to Search Console and publish a sitemap
Week 4 — verify
- Re-run the same crawl and compare before and after (62 → target 80+)
- Export GSC impressions and indexing as the new baseline
- Deliver a one-page result comparison
7. What you receive
- This audit report (web page and PDF)
audit_result.json— the raw crawl data, so you can recompute every figureseo_audit.py— the zero-dependency crawler itself, so you can re-run it any time- A 30-day execution checklist you can tick off item by item
Prepared by Kevin Huang · Technical SEO audit · 2026-11-11
Data source: local crawl with
Data source: local crawl with
seo_audit.py, not third-party estimates. Every value here is reproducible by re-running the script against the same site.