Wergrauf — plumbing store
The client rebranded and wanted to raise the level of the site. For the new brand I built a plumbing store from scratch on a pure stack — no CMS, no frameworks, no MySQL. Product data lives in JSON files that sync automatically with Google Sheets. The full cycle: a catalog of 9 categories, product pages, cart, checkout and online payment, moderated reviews, a custom admin panel, e-commerce analytics and SEO. The site holds 90–100 on PageSpeed Insights on both desktop and mobile.
Architecture
A deliberately light “database-free” architecture: instead of a CMS and SQL, file storage plus a Google Sheets integration acting as a convenient content panel.
- The data source is the Google Sheets API: one spreadsheet, a separate sheet per category. A PHP sync script pulls the data through the API and saves it as JSON — the content manager maintains the product range in a familiar spreadsheet and the site updates at the press of a button.
- Image localisation: during sync, external product photos are downloaded to the server, converted to WebP and renamed by slug. Idempotent, with a fallback if something fails.
- An override layer: manual edits from the admin panel (meta tags, hidden products, ordering) are applied on top of the spreadsheet data — the spreadsheet stays the source of truth, but any field can be overridden locally.
- Server-side rendering of the catalog for proper internal linking and SEO; client-side JS only handles filtering and sorting.
Key features
Catalog and products: 9 categories, a single server-side template for both the product page and the catalog; product pages with a gallery, photo switching, specifications and “similar products” / “from this collection” blocks; client-side filtering by price (dual slider), model, colour and collection, plus sorting.
Cart, order, payment: a client-side cart (localStorage), checkout and one-click purchase, online payment via Ozon SBP, an order status page that polls the payment, and new-order notifications in Telegram through a bot.
Reviews: a form with up to 4 photo uploads and three layers of anti-spam protection (honeypot + fill-time check + arithmetic captcha), stored as JSON and moderated through the admin panel.
A new-arrivals subscription that stores the subscriber list and shows it in the admin panel.
Custom admin panel
Entirely hand-written, with authentication on PHP sessions.
- A dashboard with per-category statistics.
- One-click manual sync with Google Sheets, with a result log.
- Viewing and editing the products in each category, including meta tags (title/description) for SEO.
- Adding manual products on top of the synced ones and editing the homepage content.
- Review moderation, a subscriber list and a sync log.
- Service tools: batch image optimisation and system junk cleanup.
Performance (PageSpeed Insights)
The site was brought up to 90–100 Performance on desktop and mobile.
- Responsive image sizes: for every product photo the sync generates derived sizes (product page ~600px, thumbnail ~160px) alongside the original used in the gallery — product images are 65–70% lighter, and the thumbnails under the main photo went from ~65 KB to ~2 KB.
- WebP everywhere — products and logos (via <picture> with a fallback).
- Cumulative Layout Shift eliminated: explicit width/height on every image.
- Load prioritisation: fetchpriority on the main image (LCP), lazy-loading for the rest, preconnect to the analytics domain, defer on scripts.
- Contrast, headings and fonts tuned for mobile.
SEO
- Schema.org / JSON-LD: Product + Offer (dynamic availability and priceValidUntil), BreadcrumbList on product pages, Organization + WebSite on the homepage.
- Canonical URLs, keyword-first title tags, a correct heading hierarchy, <main> landmarks and semantic markup.
- Auto-generated sitemap.xml and robots.txt.
- A YML feed for Yandex.Direct (product campaigns, smart banners) that refreshes itself after each catalog sync.
- Accessibility: ARIA labels, WCAG contrast, accessible navigation.
Analytics
Full e-commerce analytics on Yandex.Metrica: goals and a dataLayer on the key actions (add to cart, order, one-click purchase, successful payment, subscription), protection against double-firing goals, webvisor and clickmap. Purchases are tracked with de-duplication during payment polling.
What makes it interesting
- Zero dependence on heavy infrastructure: no CMS, no SQL, no framework — and still a full store with payments, analytics and an admin panel.
- Google Sheets as the content backend — an unconventional integration, but a convenient one for the client.
- Performance as a deliberate priority: image optimisation is built into the data pipeline rather than bolted on afterwards.
- The full cycle by one person: architecture, backend, frontend, integrations, SEO, deployment and support.