Case Study - Reusable E-Commerce Engine – TanosMotorsport

A production-grade, reusable e-commerce engine built on Next.js 15 and Strapi 5 — with ISR product pages, multi-currency support, and Horizon Translate integration for full multilingual storefronts.

Client
TanosMotorsport
Year
Service
E-Commerce · Headless CMS · Multilingual Infrastructure

Overview

TanosMotorsport is an online store specialising in van and sports car modifications — a niche, technical catalogue where product pages need rich specs, multi-currency pricing, and a genuinely multilingual experience for a European audience.

We didn't just build a store. We built the engine that powers it — and designed every layer to be extracted, reused, and deployed again under a different brand without rewriting core logic.

The reusable engine architecture

The project is structured as a pnpm workspace monorepo:

  • /app — Next.js 15 (App Router) frontend, fully typed with TypeScript
  • /backend — Strapi V5 headless CMS with custom admin plugins
  • /packages/email — transactional email templates shared across deployments
  • /packages/globalcomponents — UI component library reusable across storefronts

The backend exposes a clean REST API with no frontend-specific coupling. Swapping the frontend or running two storefronts against the same backend is a configuration change, not a rewrite.

TanosMotorsport storefront architecture

ISR: fresh products without full redeploys

Product pages live at [locale]/product/[id]. At build time, generateStaticParams pre-renders the top products across all three locales — giving sub-100ms response times for the most visited pages from the first request.

// ISR: revalidate every 2 minutes — fresh pricing, no full redeploy
export const revalidate = 120
export const dynamicParams = true

export async function generateStaticParams() {
  const products = await getProductsServer({ page: 1, limit: STATIC_GENERATION_LIMIT })
  const locales = ['pl', 'en', 'de']
  return locales.flatMap(locale =>
    products.map(product => ({ locale, id: product.id.toString() }))
  )
}

Long-tail products that weren't pre-rendered fall through to on-demand rendering via dynamicParams = true — rendered once, then cached. The 2-minute revalidate window means a price update in Strapi is live on all product pages within 120 seconds, with zero server downtime and zero cache-clear scripts.

Horizon Translate: static + dynamic multilingual pages

Integrating multilingual content in a product catalogue is harder than it looks. Product titles, descriptions, and spec labels arrive in Polish from the CMS and need accurate, consistent translations in English and German — for SEO-indexed static pages, not just client-side rendering.

We integrated our own Horizon Translate pipeline as the translation layer. The system uses a two-tier cache:

L1 — in-memory: Hot translations served in microseconds during a running server session.

L2 — disk cache: Persistent across restarts and deployments. The cache key is a SHA-256 content hash of the source strings — so when product content changes in Strapi, the hash changes, the cache misses, and a background re-translation fires automatically. No manual invalidation.

// SHA-256 of sorted source strings → automatic invalidation on content change
export function contentHash(strings: Record<string, string>): string {
  const sorted = Object.keys(strings).sort()
    .reduce<Record<string, string>>((acc, k) => { acc[k] = strings[k]; return acc }, {})
  return crypto.createHash('sha256').update(JSON.stringify(sorted)).digest('hex').slice(0, 20)
}

Writes are atomic (.tmp + rename) to prevent corrupt reads under concurrent requests. TTL is 7 days — but because the hash encodes the content, a 7-day-old cache entry is still valid if the product description hasn't changed.

Translation cache architecture diagram

A /api/translate-warm endpoint allows pre-populating the disk cache on deployment — ensuring cold-start product pages never hit the translation API live during the first request.

Multi-currency and checkout

The storefront handles PLN, EUR, and GBP with live exchange rates fetched via a background API route. Prices are stored in PLN in Strapi and converted client-side using a CurrencyContext — avoiding CMS data duplication while keeping pricing accurate for international buyers.

Authentication uses Clerk, with a full checkout flow and order management accessible from the user dashboard.

Result

A complete, production-deployed e-commerce platform for a niche automotive brand — and a reusable engine that can be licensed, forked, or adapted for any product-driven business. The combination of ISR, content-hash-driven translation caching, and a clean monorepo package structure means the next deployment starts from a working platform, not a blank canvas.

More case studies

Open-Source AI Context Toolkit – Squick

An open-source toolkit that pre-computes structured project context for AI coding agents, eliminating repeated token-expensive codebase scans on every prompt.

Read more

Interactive Broadcast Platform – PlayPuls (Poland)

Advanced HbbTV infrastructure for one of Poland's leading television networks, bringing modern interactivity to traditional broadcast television.

Read more

Tell us about Your BIG IDEA

Our offices

  • HQ — Dubai Area, UAE
    Sharjah Media City (Shams)
    Al Messaned, Al Bataeh
    Dubai Metropolitan Area, UAE
  • European Office — Warsaw
    Chelmska 21
    00-724, Warsaw, Poland