Background
A UK-based B2B software development agency specialising in custom web applications, Laravel, headless CMS, and membership platforms engaged Peacock Search for a one-off technical and strategic SEO audit. The agency had a strong market position — accredited ecosystem partnerships with Laravel, Statamic, and Stripe; genuine recognition in developer communities; and an active content programme with 330+ published articles.
The brief centred on a specific commercial problem: one of their main service pages was generating over 124,000 monthly impressions in Google Search Console, but converting at just 0.1% CTR with an average position of 17–19. They knew it had ranked higher before and wanted to understand both why it had dropped and what broader issues were holding the site back.
The answer, when the data came together, was a set of five compounding technical problems operating in parallel — none catastrophic in isolation, but together creating a meaningful drag on the entire site's performance.
Baseline data
| Metric | At audit |
|---|---|
| Total URLs crawled | 1,831 |
| Indexable pages | ~390 |
| Published articles | 330+ |
| Monthly impressions, key service page | 124,000 |
| CTR, key service page | 0.1% |
| Average position, key service page | 17–19 |
| Sitewide average CTR | 0.38% |
| Sitewide monthly impressions | 1,139,900 |
| Sitewide monthly clicks | 4,352 |
| Average Lighthouse performance score (423 pages) | 51.6 / 100 |
| Average Largest Contentful Paint | 7,033ms |
| Pages with structured data | 0 |
| Pages with broken hreflang | 422 |
The gap between impressions and clicks is the clearest signal: 1,139,900 monthly impressions producing only 4,352 clicks is a 0.38% sitewide CTR. On a site with real authority and strong content, that gap is almost always technical and on-page — not a content problem.
What we found
The overall SEO health score at audit was 47/100. The site had genuine strengths — ecosystem-level backlinks from laravel.com, statamic.com, packagist.org, GitHub, and Awwwards; clear topical authority in its niche; and an active content programme. The issue was five systemic problems operating in parallel.
1. Site speed failures across the entire site
Not a single service page or article passed Core Web Vitals on lab data. The commercial homepage scored 49/100 with an LCP of 4,651ms and a CLS of 0.705 — well above the 0.1 acceptable threshold. Key service pages were worse. The average LCP across the site was 7,033ms against a "Good" threshold of 2,500ms.
Unused JavaScript was affecting 98.6% of pages (average saving: 1,208ms per page). Render-blocking requests were present on 94.6% of pages. 926 images exceeded 100KB — representing 79.9MB in optimisation potential. Zero HTTP caching was in place across 100% of pages, leaving 208.9MB of assets uncached on every load.
Core Web Vitals are a ranking factor. At these scores, every page on the site is disadvantaged in the algorithm — independently of content quality or backlink authority.
2. Hreflang completely broken across 422 pages
Every page except the homepage had hreflang tags — but every one of those tags pointed to the homepage URL instead of the page's own URL. So /services/laravel-development was telling Google its English (en-GB) version was https://[domain].com/, not itself. Google either ignores broken hreflang entirely or consolidates all international signals to the homepage — either outcome was harmful. The recommendation: remove hreflang entirely (appropriate for a single-language, single-region site) or correct the self-referencing implementation across all pages.
3. Zero structured data deployed anywhere
Not a single page had structured data. For a site with 330+ articles, multiple service pages, FAQs, breadcrumb navigation, and a defined agency identity, this represented a significant missed opportunity for rich results, authorship disambiguation, and clarity in Google's knowledge graph. Recommended schema types were mapped to specific page types: Organization (homepage, about), Service (each service and technology page), Article/BlogPosting (all articles), FAQPage (service pages with Q&A sections), BreadcrumbList (site-wide — the breadcrumb HTML was already present, just not marked up), and LocalBusiness/ProfessionalService (about and contact).
4. Invalid HTML in <head> on every page
100% of pages had an invalid HTML element in the <head>. When a browser or Googlebot encounters this, it can stop processing the <head> at that point — meaning canonical tags, hreflang tags, and meta robots directives appearing after it may be ignored. Given the broken hreflang above, this compounded the problem: the hreflang tags were likely being ignored for two separate reasons simultaneously.
5. On-page SEO issues at scale
| Issue | Count |
|---|---|
| Missing or duplicate title tags | 64 pages |
| Title tags over 60 characters | 184 pages (43%) |
| Missing meta descriptions | 69 pages (16%) |
| Meta descriptions over 155 characters | 116 pages (27%) |
| Missing H1 | 75 pages (17%) |
| Multiple H1 tags | 26 pages |
| H1 appearing non-sequentially in DOM | 362 pages (83%) — site-wide theme issue |
The key commercial page driving 124,000 monthly impressions had a meta description that was either absent or insufficiently competitive to drive clicks from position 17–19. Rewriting it with a clear value proposition and keyword-relevant copy was identified as a quick win with direct impact on CTR.
Additional findings
Of 414 referring domains, 202 were flagged as spam by Ahrefs — including evidence of automated link-buying campaigns actively targeting the domain. The legitimate profile was strong (laravel.com, packagist.org, Awwwards, GitHub), but the spam domains represented a meaningful manual action risk. A disavow file was prepared as part of the deliverable.
A gap analysis against five direct competitors identified 519 relevant keywords where competitors ranked and the client did not. High-opportunity targets included "statamic" (500 monthly searches, KD 34 — the client is a recognised Statamic agency), "shopify development company" (700 vol, KD 2), "custom software development" (1,500 vol, KD 2), and "laravel cms" (900 vol, KD 9).
The client scored well on Experience (real project case studies, ecosystem accreditations) and Expertise (deep technical content, partnership status with Laravel, Statamic, and Stripe). The main gaps were in Authoritativeness and Trustworthiness: no named authors on articles, no testimonials on service pages, no Google Business Profile, no schema establishing organisational identity, and no review signals from third-party platforms.
What was working
- Ecosystem-level backlinks — laravel.com, statamic.com, packagist.org, GitHub, Awwwards. A legitimate authority foundation most agencies cannot build quickly.
- Clear topical depth — 330+ articles covering the technical stack in genuine detail. Content quality was not the problem.
- Established partnership accreditations — Laravel, Statamic, and Stripe partnerships provide trust signals that structured data and E-E-A-T fixes can amplify.
- Breadcrumb HTML already in place — just not marked up with schema, meaning BreadcrumbList structured data could be added without any content changes.
Deliverables
The audit was delivered as a structured Excel workbook with 18 tabs, formatted for a non-technical client audience with colour-coded severity indicators, data tables, and written recommendations throughout.
- 18 tabs covering crawlability, on-page SEO, technical SEO, site architecture, backlinks, organic performance, content gap, and E-E-A-T assessment
- Glossary tab explaining terminology for non-technical stakeholders
- Prioritised action plan with effort/impact scoring for each recommendation
- Disavow file — ready for Google Search Console submission, covering 202 spam referring domains
- Sitemap fix list — URLs to remove from the XML sitemap (4xx, 3xx, and canonicalised pages)
- Schema recommendations — JSON-LD types mapped to specific page templates
- E-E-A-T audit — scored assessment across all four pillars with eight specific actions
- Content gap analysis — 519 keyword opportunities with competitor comparison and cluster groupings
Priority actions
The top six items were sequenced by impact and implementation effort:
JavaScript deferral, image optimisation, HTTP caching — a developer sprint. Highest ROI item on the list: affects every page, directly impacts rankings, and unblocks other improvements.
Single developer task. Immediate resolution of a high-severity signal conflict on 422 pages. Removing entirely is a valid option for a single-language, single-region site.
Rewrite title and meta description, add Service schema, improve internal linking to the page, and address page speed specifically for this URL. This page has 124,000 impressions — incremental CTR gains here have outsized commercial impact.
Identify and move the invalid element before critical meta tags. One developer fix that potentially unblocks canonical and meta robots processing across the entire site.
JSON-LD for Organization, Service, Article, FAQPage, and BreadcrumbList. The breadcrumb HTML is already there — schema is an addition, not a rewrite.
Clean 202 spam referring domains from the profile before algorithmic or manual action is triggered.
The opportunity
The client is ranking — but not where clicks happen. The gap between 1,139,900 monthly impressions and 4,352 clicks is not a content problem. It is a technical and on-page problem sitting on top of a strong foundation.
A site with this content depth, in this niche, with backlinks from laravel.com and packagist.org — if it passed Core Web Vitals, fixed its hreflang, deployed structured data, and addressed on-page basics — would be a materially different performer in search.
None of the priority fixes require new content. They require developer time and implementation discipline. The content is there. The authority is there. The technical debt is what is holding it back.