Building contractor
SHRUBB Building Contractors
A 40-page local site for a builder that Google could not place.

The hero photo is SHRUBB's own work. An earlier generated video loop was replaced after client review.
Project facts
- Problem
- A six-page site that named the wrong towns, scored about 30 out of 100 in our audit and ranked 24th for builders in Oxted.
- Approach
- We rebuilt it as 40 pages Google can list, with a page for every service and town, and redirected every old web address.
- Result
- Live since 11 September 2026, at about 94 on-page by our own score. It is too early to report ranking movement.
- Client
- A.Shrubb Ltd
- Where
- Lingfield, Surrey
- Year
- 2026
- Status
- Live
- Work
- Local SEO sites, Brand websites
- Visit
- ashrubb.co.uk
Our role
Built with
Next.js 16 (App Router), React 19, TypeScript, Tailwind CSS v4, next/font (Fraunces, Hanken Grotesk), Resend API, GA4 with Consent Mode v2, Server-side enquiry reporting, IndexNow, node:test, Vercel
The problem
SHRUBB builds extensions, new homes and driveways for homeowners, and runs void-property and reactive-maintenance work for councils and housing providers. The old site had six pages that all shared one title and one description. The main page heading was the logo image, and the only keyword tag named Redhill, Reigate and Woking instead of Oxted.
Our baseline audit scored the site about 30 out of 100: On-Page 22, Local 20, Technical 30, Content 38, Trust 35. It had no postal address and no structured data for Google. The sitemap, the file that lists pages for search engines, returned an ordinary web page, and the template still shipped an Internet Explorer 6 upgrade banner. On a phone the menu button was invisible, so the phone number was two pages deep.
A rank check on 24 August 2026 put SHRUBB 24th for "builders in Oxted". It did not appear in the top 50 for extensions, new builds or resin driveways. Off-site effort had targeted the wrong town and an old company name, while the website itself had not been touched.
What we did
We wrote the baseline down before designing anything: a scored audit, a keyword and intent map per page, and a competitor review. The competitors had 10 to 12 town pages each, and none of them used structured data. That gap set the build targets: deep service pages, a page per town, and structured data on every page type.
The site is built in Next.js 16, with every service and town page generated from two structured data files. Colour and type come from the SHRUBB logo: navy and steel grey, with a brass accent kept for calls to action. Every hero carries the quote button and a tap-to-call number.
Before launch we applied the client's feedback in full, mapped every old web address to a new one, and set up enquiry counting that does not depend on cookie consent. The site went live on 11 September 2026. We added quote-form email, Google Analytics behind a cookie consent banner and enquiry counting in the two weeks after.
Before and after


What we considered
The decisions behind the build, with the reasoning and the evidence for each.
StrategyA written baseline before a pixel moved
Local SEO claims are cheap unless there is a dated 'before'. We scored the old site against a fixed rubric and recorded live Google positions, so any later change can be measured against the same test.
- Five scored categories: On-Page 22, Local 20, Technical 30, Content 38, Trust 35
- Rank snapshot from a UK connection on 24 Aug 2026: 24th for "builders in Oxted", 38th for "builders Oxted"
- Map pack: third of three, with a listing that still showed a dissolved company name
- Seven findings written for the owner in plain English, none of them about how the site looks
Search26 town pages, each written from planning sources
Town pages that only swap the place name tell a reader nothing, and search engines treat them as thin content. Each area page describes the character of the place from council conservation and planning documents, and it never claims work in a town that the client has not confirmed.
- 26 towns: 11 in Surrey, 9 in Sussex, 6 in Kent, all generated from lib/areas.ts
- Sources listed in docs/area-copy-sources.md and checked on 11 Sep 2026
- A 'Check the local guidance' panel on each page links to the relevant council
- Rule in PRODUCT.md: do not invent project locations or locally completed work
SearchStructured data that describes a multi-trade contractor
SHRUBB serves three counties from one yard, with separate Surrey and Sussex lines. The JSON-LD says exactly that, so search engines get the service area and contact points as data instead of guessing from body copy.
- GeneralContractor with areaServed as three AdministrativeArea nodes, each with containsPlace towns
- Three ContactPoint entries: Surrey office, Sussex office and mobile
- Service with an OfferCatalog on service pages, plus FAQPage and BreadcrumbList
- Keyword and location title on every page, replacing one shared title
ReleaseLaunch without losing a single old web address
The old site had some links and some history in Google. Every legacy path gets a permanent redirect to its closest new page, so nothing that used to work returns a 404 on launch day.
- Eight 301 redirects in next.config.ts, including /index.php, /feedback and three renamed service slugs
- Sitemap lastModified pinned to the content date, not the build time
- The noindex privacy page is removed from the sitemap so the two signals never conflict
- IndexNow key file published to get new URLs crawled after each change
ContentClient feedback applied without argument
The owner knows what his customers trust. We changed the build to match his review: fewer claims, more of his own work, and the approvals he holds in writing.
- The generated hero video loop was removed and replaced with a real SHRUBB project photo
- The LABC award is shown without a year, and review-platform counts are removed
- Official approval logos added: LABC, Surrey County Council Approved Contractor, Resin Boundworx, SafeContractor
- 45 client-supplied job photos converted to WebP. Captions describe only what is visible, because locations are unconfirmed
ShowHide the other 5 decisions
DataEnquiries counted even when cookies are declined
Google Analytics only sees visitors who accept cookies, which is not enough to prove what the site does. Each delivered quote enquiry is also reported server-side to our own monitoring, with only the page paths attached.
- The landing page is held in memory for the visit only, with no cookie or storage, so it needs no consent
- A reload or a new tab from the site is never credited as the landing page
- The reporting call has a 3-second timeout and never throws: the enquiry email has already been sent
- GA4 events for generate_lead, phone_click and whatsapp_click
SecurityNo analytics cookies until the visitor agrees
UK privacy law (PECR) requires consent before analytics cookies are set. The consent default runs before the GA tag loads, so nothing is stored until the visitor chooses.
- Default denied for analytics_storage, ad_storage, ad_user_data and ad_personalization
- ads_data_redaction and url_passthrough set for the cookieless pings
- Ad signals stay denied on accept, because the site runs GA4 only
- GA4 loads on the production deployment only, so previews never report to the client's property
TestingThe same form rules in the browser and on the server
Form rules that differ between the browser and the server produce enquiries the office cannot answer. The rules live in one import-free file that both sides use and that Node's test runner can load directly.
- Name, phone and a 10-character message required; email optional but checked when given
- Honeypot field for bots and per-field length limits, up to 5,000 characters for the message
- 17 node:test tests across enquiry rules, landing-page logic and server-side reporting
DesignA palette taken from the logo, with one warm accent
The navy and steel grey were already on the vans and the signboards. We kept them and added one brass tone for calls to action, so the quote button is the only warm colour on the page.
- Navy #0B2455 for headings and dark surfaces, steel #6F7378 for secondary text
- Brass #C8A24B for primary buttons only, with #AB8534 for small text on paper
- Base styles in @layer base, so Tailwind v4 utilities always win and dark-on-dark text cannot happen
- The brass kicker style is limited to one or two uses on the whole site
AccessibilityA working phone path on every screen
The old mobile menu could not be seen, so phone visitors had no route to the number. The rebuild puts a visible menu, a quote button and a call button on the first screen of every page.
- 3px brass focus outline with a 2px offset on every interactive element
- Reduced motion removes reveal animations, button lift and smooth scrolling
- Click-to-call in the header on mobile and in every hero
- Business address published in the footer and on a named contact map
Colour and type
- Navy#0B2455Headings, header text and dark sections. Taken from the logo.
- Navy 950#081A3FDeepest surface and consent banner
- Steel#6F7378Secondary text and the logo's grey brick band
- Brass#C8A24BPrimary call-to-action buttons and focus outline
- Brass dark#AB8534Small accent text on light backgrounds
- Paper#F7F6F3Page background
- Ink#16202EBody text
Builders in Oxted
Semi-bold (600) with -0.01em tracking and balanced wrapping. A warm serif suits a family firm that has built locally for 20 years.
Request your free quote. Call 01883 382425.
Loaded with next/font and display: swap. A sturdy grotesque that stays legible in buttons and dense service copy.
The build, screen by screen






By the numbers
- SEO score of the old site
- ~30/100
- Source: Our audit of the old site, 29 June 2026
- Indexable pages
- 6 → 40
- Source: Our audit of the old site, then the live site's sitemap
- Town pages with sourced local copy
- 26
- Source: Counted on the live site. Local copy checked against council planning documents, 11 September 2026
- Position for "builders in Oxted" before launch
- 24th
- Source: Google search from a UK connection, 24 August 2026. A baseline, not a result
- On-page score after the rebuild
- ~94
- Source: Our own score against the same audit rubric, after the rebuild
Where it landed
The site has been live at ashrubb.co.uk since 11 September 2026. It has 40 pages Google can list: 8 service pages, 26 town pages and 6 core pages. Structured data tells Google the business type, services, service area and common questions. Quote requests arrive at the office by email.
On the same audit rubric, our own score for the parts we control is about 94 for on-page, 95 technical, 92 content and 85 for on-site local signals, against a baseline of about 30. Rankings are monitored from the 24 August snapshot. It is too early to report movement, so we do not claim any.
The off-site work is on a written list for the owner: correct the Google Business Profile, use one trading name everywhere, and stop citing the dissolved company.