NextWoo
Audit example · Online coffee store

We audited an online coffee store. Here is the whole thing.

A specialty coffee roaster selling ground coffee and beans direct to consumers, plus wholesale. Seventeen products, sixty-four articles, WooCommerce on a commercial theme. This is the audit we sent them, with everything identifying the business removed and nothing else changed. It is published so you can judge the depth of the work before asking for one on your own store.

Coffee store audit dashboard with performance gauges and a findings list
Sector
Specialty coffee — ground and whole bean, retail plus wholesale
Platform
WordPress + WooCommerce
Frontend
Commercial multipurpose theme plus a page builder, four UI plugins
Catalog
17 products in three pack sizes, 64 articles
Hosting
Single regional server, page cache installed, no CDN
Audit scope
6 templates, mobile and desktop, 60+ URLs inspected

Why this one has no name on it

The owner has not asked us to publish a named case study, so we have not published one. Business name, domain, product names, prices, contact details, staff names and every branded screenshot are removed. We name a client only with written consent, and normally only after the work is finished. All of this was observed from the public web — but public data and a public critique are two different things, and the difference is consent.

What the numbers said before we read a single page

Six measurements that framed everything else.

1.7–2.2 s

of pure PHP per page

The gap between a static file and an HTML page from the same connection, measured with a stopwatch. A page cache was installed and being bypassed.

0.518

CLS on the mobile catalog

Against a 0.10 threshold. One page-builder container accounted for 0.5176 of it on its own.

242

requests on the catalog page

98 stylesheets and 105 scripts, on a page whose job is to list twelve products.

850 KB

for two thumbnails

Two full-size PNGs displayed at 191 px wide, on a page that already serves 24 KB WebP for other products.

0

analytics tags found

Across all six templates. No GA4, no Tag Manager, no pixel, no regional alternative.

30

five-star reviews, invisible

Recorded in the product schema across 14 of 17 products, and displayed nowhere in the catalog.

Measured performance

Ten Lighthouse runs across six templates, with rendering metrics calibrated to the PageSpeed Insights reference device rather than to fast developer hardware — the conservative reading. Server response, layout shift, request counts and byte weights are reported exactly as measured.

TemplateDevicePerfLCPCLSServerRequests
HomepageMobile606.3 s0.0111,700 ms200
CatalogMobile3510.4 s0.5182,236 ms242
CatalogDesktop732.2 s0.0082,026 ms242
ProductMobile606.4 s0.0111,858 ms220
CartMobile536.0 s0.0691,952 ms190
Blog indexMobile558.7 s0.0862,153 ms166

Checkout has no row because it could not be reached — with items in the cart it redirects to a login screen before rendering. That turned out to be the most expensive finding in the audit.

The one failing metric

0.518

Cumulative Layout Shift, catalog

Google threshold0.10
This store0.518

0.5176 of that 0.518 came from a single page-builder container — the filter block, which finishes building after first paint.

Method

What we checked on this store

Everything was observed directly on 9 August. No order was placed and no intrusive testing was performed — this is a store-quality audit, not a penetration test.

  1. 01

    Speed

    10 Lighthouse runs across 6 templates, mobile and desktop; server response measured separately with curl to separate network from PHP.

  2. 02

    A real browser

    Headless Chrome at 390×844 and 1440×900: full-page captures, a genuine add-to-cart and a real checkout attempt.

  3. 03

    Crawling

    60+ URLs inspected directly: all four sitemaps, robots.txt, filter parameters, legacy addresses, utility pages.

  4. 04

    Structured data

    JSON-LD parsed from all 17 product pages, four articles, the homepage, the catalog and the contact page.

  5. 05

    Content

    17 product descriptions and 4 full articles read; 6-gram overlap computed to find duplication between pack sizes.

  6. 06

    Off-site visibility

    Brand search spot checks only. Not rank tracking and not a backlink audit — no ranking positions are claimed anywhere.

Findings

Eight of the twenty-three findings

Every finding in the report has the same four parts: what is happening, the evidence, what it costs, and what to change. These are the eight that carried the most money.

F12Critical

Customers could not buy without creating an account

Conversion

Evidence

With two items in the cart, the checkout URL returned 302 to the account page, then to a login screen. The redirect parameter sent the customer to the homepage after signing in — not to the checkout they were trying to reach. Verified twice: once with a scripted session, once in a real browser.

Why it matters

Forced registration is among the largest single causes of checkout abandonment, and here it was compounded three ways: the interruption arrived with no explanation, it required an SMS one-time password, and completing it did not return the customer to the purchase. A first-time buyer of one bag had to create an account, wait for an SMS, then find their cart again.

Fix: Enable guest checkout, offer the account after the order, and fix the redirect. Hours of work, not days.

F13Critical

The store had no analytics of any kind

Measurement

Evidence

Six templates searched for every common tag signature — Google Analytics, Tag Manager, Meta, and the regional alternatives. Zero occurrences. The only third-party host the frontend called was a CDN serving a phone-number library.

Why it matters

Nobody could tell how many people reached the cart, how many hit the login wall above, or what any fix would be worth. It also meant we could make no claims about their traffic or conversion rate — and we said exactly that in the report instead of estimating.

Fix: GA4 through Tag Manager with the five ecommerce events, verified firing in DebugView. Do it before anything else so the rest becomes measurable.

F1Critical

Every page was built from scratch on every request

Performance

Evidence

A static stylesheet returned in 0.41–0.61 s from the same client and connection; HTML took 2.04–2.62 s. The difference is server-side generation. A page cache was installed but bypassed — a login plugin set a cookie on every single response, including for anonymous visitors and crawlers, and a Set-Cookie on an anonymous page is a standard cache-bypass trigger.

Why it matters

Two seconds passed before the browser received a byte it could render, and almost none of it was network. It is the floor under every other metric on the site and it applies to search crawlers as much as to customers.

Fix: Exclude that one cookie from the cache rules and switch full-page caching on for guests. A configuration change, not a project.

F11High

Thirty five-star reviews existed and appeared nowhere in the catalog

Conversion

Evidence

The product schema recorded 30 reviews across 14 of 17 products, all rated 5.00. Searching the rendered catalog and category pages for star markup returned only the stylesheet link — the theme downloaded the rating CSS on every category page and then rendered no stars at all. No ratings on the homepage either, and no 'best rated' module anywhere.

Why it matters

The cheapest conversion asset a store can have was already earned, already in the database, and simply not displayed anywhere a customer makes a decision. A shopper scanning twelve identical cards had no signal that one product had six five-star reviews and its neighbour had none.

Fix: Turn ratings on in the product loop. The CSS is already loading — this is a template change and the highest return-per-hour item in the whole report.

F8Critical

Navigation was organised by pack weight, and mobile had no categories at all

Navigation

Evidence

The top-level product menu led with '1000 g coffee' and '350 g coffee' — attribute archives, not categories. Two further entries were marked 'coming soon' and contained zero products, and one was a dead anchor. On a 390 px viewport the rendered menu contained no category links whatsoever: the theme's off-canvas category drawer had never been configured, and its setup placeholder was still sitting in the page source of every URL.

Why it matters

Nobody decides 'I want 350 grams' before deciding which coffee. On mobile — the majority of traffic — the only route into the catalog was the shop page, with no way to browse by type.

Fix: Restructure around intent: by brew method and by blend. Weight becomes a filter, not a category.

F4High

The attributes that decide a coffee purchase were not recorded as attributes

Product data

Evidence

Across 17 products: tasting notes on 16, brewing suitability on 15, weight visible on 7 — but roast level, acidity, body and intensity on none of them. Origin existed on two. Two duplicate taxonomies were in use for the same field, so identical data was stored in two places depending on the product. Roast and origin were stated in prose, 400 and 700 words into the description.

Why it matters

Nothing could be filtered, compared or shown on a product card, because the data was paragraphs rather than structure. This one finding blocked the catalog navigation, the filters and the product cards simultaneously — and it is why a customer could not tell two similarly priced blends apart without opening both pages.

Fix: Add roast, intensity, acidity and body as 1–5 attributes, plus origin and grind, and put the profile above the Add to Cart button.

F10High

The homepage led with 15-kilogram wholesale sacks

Merchandising

Evidence

The 'newest products' block on the homepage opened with two 15 kg wholesale sacks — one of them out of stock — followed by two bundles. No consumer pack size appeared on the homepage at all. The same four items were recommended at the foot of a retail product page costing roughly a thirtieth as much. Underneath that, the price ladder had no ladder: per kilogram, the 1 kg pack cost the same as the 350 g pack and in several cases slightly more, and the 15 kg sack saved a café barely 2% over buying fifteen 1 kg bags.

Why it matters

The shop window showed a product most visitors could not use, and one of the two could not be bought. And no customer had a financial reason to trade up, so average order value was capped by the pricing structure itself.

Fix: Retail-first homepage, related products restricted to the same tier, wholesale moved behind its own journey, and a real volume discount.

F18Critical

A previous English-language section had been deleted without redirects

SEO

Evidence

A brand search in English returned ten indexed URLs under the old language prefix. All ten returned 404. The cached descriptions also contradicted the live catalog on product composition, so the few people who did find the brand in English were reading specifications that no longer matched what was for sale.

Why it matters

Every international visitor who found the brand in search landed on an error page, and the authority those pages had accumulated was being discarded rather than inherited. For a producer with wholesale pack sizes and export-appropriate products, that is a channel that existed and was switched off.

Fix: Redirect the old URLs this week. Then decide whether English is worth rebuilding properly — for a 17-product catalog it is a matter of weeks, not months.

What the store was already doing well

An audit that only lists problems is a sales document. These were genuine strengths, and they changed the recommendation.

  • Rank Math configured competently — sorting and price-filter parameters canonicalised correctly, search and cart set to noindex, 404s handled.
  • Legacy product URLs redirecting properly to their current locations after an earlier category-base change.
  • Original product copy in the local language, not translated manufacturer boilerplate.
  • Sixty-four substantial articles that link into product pages with contextual in-sentence anchors — three to six per article, not a widget.
  • Real customer reviews with correct schema, and an Enamad trust seal for the local market.
  • Structured product data that parses cleanly, with correct currency, availability and price validity.

What we told them to do, in order

Twenty-three findings condensed into three phases. The order is the recommendation — most of the value sits in the first one.

  1. 1

    Phase 1 — configuration, not development

    1–2 weeks

    • Analytics and Search Console first, so everything after it is measurable
    • Guest checkout on, post-login redirect fixed
    • Full-page caching switched on by resolving the cookie conflict
    • Tax shown inclusive instead of appearing at the cart
    • Dead language-prefix URLs redirected
    • Height reserved on the filter container to kill the 0.518 layout shift
    • Two oversized thumbnails resized; cache headers added to scripts and images
    • Star ratings turned on in the product loop
  2. 2

    Phase 2 — catalog, merchandising and SEO structure

    3–6 weeks

    • Roast, intensity, acidity, body, origin and grind added as real attributes
    • Navigation restructured around brew method and blend; mobile category menu configured
    • Filters moved into a mobile drawer and extended to filter by coffee, not just price
    • Homepage and related products made retail-first; wholesale separated; volume discount introduced
    • Duplicate category URLs consolidated; every category given an H1, an intro and a description
    • Structured data completed — brand, breadcrumbs, organisation, readable attribute labels
    • Health-claim blocks replaced with brewing parameters; six-shot photography set per product
  3. 3

    Phase 3 — a bilingual storefront on the same backend

    scoped in parallel

    • New customer-facing storefront in Next.js; WooCommerce stays as the commerce backend
    • English as a real second locale with hreflang pairing and the old URLs redirected onto it
    • Premium product presentation — large photography, blend and roast expressed visually
    • A guided finder and a full comparison table, built on the attributes added in Phase 2
    • A separate B2B track for wholesale and café supply, in both languages

What we recommended — and what we did not

We build Next.js storefronts, so it would have been easy to make all of the above an argument for one. That is not what the evidence said, and the report said so plainly.

The three most expensive findings — forced registration, missing analytics, uncached HTML — are configuration. A rebuild fixes none of them. Shipping a fast new frontend onto a checkout that cannot take a guest order would have been an expensive way to change nothing. Those went into a phase that runs on the existing site, in days, before anything else.

The frontend case was real, but separate: a theme, a page builder and four plugins each rendering their own interface; 242 requests on a page whose job is to list twelve products; a failing layout shift caused by a builder container; a mobile category menu that was a theme setting nobody had found. We recommended replacing the storefront while leaving WooCommerce as the backend — and listed the trade-offs, including checkout integration work that buys parity rather than improvement.

An audit that recommends the same thing every time is a price list, not an audit.

The same audit, on your store

Free, written, and yours to keep. We measure your templates, read your product pages and tell you what is actually costing you — including when the answer is that you do not need us.