work details

Ensotek — Shared-Core Multi-Brand B2B Platform Suite

A multilingual industrial B2B platform family for Ensotek, Kühlturm and Karbon Kompozit, using shared packages with separate deployments and databases for each brand.

Client

Ensotek

Start

15 Sep 2025

Completed

Website

ensotek.de
Ensotek — Shared-Core Multi-Brand B2B Platform Suite interface and project preview
Description

A multilingual industrial B2B platform family for Ensotek, Kühlturm and Karbon Kompozit, using shared packages with separate deployments and databases for each brand.

Case study

Challenge

Ensotek's four brands shared similar workflows but had different language, market and legal requirements. Four separate codebases would multiply maintenance, while a single-database setup carried the risk of data and settings leaking between brands.

Approach

Shared Fastify modules, admin interface components, types and configuration were gathered into one package layer, used by each brand with its own repository, database and deployment. Modules matured on one site before moving into the package; the quote module became shared with a per-site PDF template, and Kühlturm was separated into its own database.

Outcome

All four sites now run independently while drawing on the same core; a shared fix can be used across the family, while a data change on one site stays on that site. ensotek.de is live as the family's main site in three languages, with customer accounts and extensive technical content.

Tools

Next.js, TypeScript, Fastify, Drizzle ORM, MySQL, Bun, Docker, Nginx

Key Features
  • 4 domains, 4 separate databases, one shared package layer

  • Shared Fastify modules: products, quotes, catalogue, library

  • Shared quote module with a branded PDF template per site

  • ensotek.de: German by default, DE/EN/TR content

  • Customer account: support tickets and notification dashboard

  • Content-ID based hreflang, 308 redirects and real 404s

  • Brand name and logo come from site settings, not code

  • Versioned, read-only content contract for Tanitio

  • API bridge for managing site content from the ERP

Technologies Used
  • Next.js

  • TypeScript

  • Fastify

  • Drizzle ORM

  • MySQL

  • Bun

  • Docker

  • Nginx

Design Highlights
  • Each brand speaks its own language to its own buyers; what is shared is the workflow, not the interface

  • On ensotek.de, language pairing follows content IDs rather than slugs, so translated URLs lead to the right counterpart

  • Product pages render on the server, and icon and theme CSS were cut down to the subsets in use

  • A dashboard that brings support tickets, notifications and quote shortcuts together for registered customers

  • A brand audit at the release gate: a setup for a new company never shows another brand on screen

Details

Ensotek is online today under four domains: the Germany-based main site ensotek.de, ensotek.com.tr for the Turkish market, the sub-brand kuhlturm.com for German-speaking markets and karbonkompozit.com.tr for composite manufacturing. Each has its own language, buyer and legal framework, yet the core workflows are the same: product catalogue, technical library, quotes and catalogue requests. This case study covers the shared core that produces all four sites from one software family, and ensotek.de, the first and most comprehensive member of that family.

Context: why a shared core?

There were two easy routes, and both carried risk. Copying four separate codebases would mean fixing every bug four times and letting the sites drift apart over time. A classic SaaS running on one database with a tenant ID brought the risk of one brand's data or settings leaking into another's; in fact, while two of the sites still shared a database before they were separated, this showed up as a real problem. The chosen model sits between the two: shared packages, with a separate repository, database and deployment per brand. To name it honestly, this is not a single-database multi-tenant SaaS but a multi-brand platform family with a shared core.

The shared core

The “packages” layer, linked through a Bun workspace, consists of five packages:

  • shared-backend: Fastify modules for authentication, storage, site settings, products, categories and subcategories, gallery, references, reviews, library, custom pages, quotes, catalogue requests, contact, newsletter, notifications, audit log, Telegram, email templates, menu, footer, slider, services and support tickets; MySQL, JWT, Redis, Sentry, Swagger and static file plugins; auth, role and locale middleware.
  • shared-ui: a data table and shared interface components for the admin panels.
  • core, shared-types, shared-config: the front-end API layer, shared types, base TypeScript settings and Tailwind design tokens.

The sites use the core to different depths. ensotek.de is first-generation code with mostly local modules; ensotek.com.tr runs almost entirely on shared modules, with only four local ones. This gradient is deliberate: a module matures on one site first and then moves into the package. The quote module is an example: it now lives in the shared package, and each site supplies only its own branded PDF template. Brand name, logo and contact details come from site settings rather than code, and a brand audit that runs before each release catches brand names hard-coded into source.

ensotek.de: the main site

ensotek.de is live with German as default and English and Turkish versions, and has the broadest content structure in the family:

  • Products and spare parts, services, industrial/HVAC/process solutions, projects and references
  • Technical library, quality certificates, mission and vision, team, news, blog and FAQ
  • Quote form, catalogue request, contact, and legal pages including a German-compliant Impressum
  • Customer account: after registration and login, a customer dashboard shows support tickets by status and priority, counts unread notifications and offers shortcuts to quote and catalogue requests

For search, language pairing is based on content IDs rather than slugs: even when a product's German and Turkish URLs differ, hreflang points to the right counterpart. Old URLs redirect with 308, missing content returns a real 404, and the sitemap covers all content in all three languages. LocalBusiness, FAQ, Breadcrumb and Article structured data and llms.txt are live. For performance, product pages are rendered on the server, and icon and theme CSS were reduced to the subsets actually used.

Admin panels

Each site has its own panel built on Next.js 16 and Redux Toolkit. The ensotek.de panel manages products and spare parts, categories, services, projects, references, library, custom pages, quotes (detail and PDF), catalogue requests, contact messages, support tickets, FAQs, slider, menu, footer, email templates, Telegram, users, roles, the audit log and site settings. The panel also includes a knowledge base screen for an AI-assisted support chat; the chat infrastructure is in place but is not currently enabled on the public site.

Technical architecture and security

  • Stack: Next.js 16, React 19, next-intl, React Query, Tailwind CSS v4; Fastify 5, Drizzle ORM, MySQL, Zod, Bun; API documented with Swagger.
  • Isolation: each site's database user is authorised for its own database only; when Kühlturm was separated, its media files also moved to site-specific storage.
  • Security: the application refuses to start if JWT and cookie secrets are missing; all admin endpoints require authentication and the admin role; public settings endpoints never return secret values.
  • Delivery: PM2 processes behind Nginx, with deployment scripts that include backup, health check and rollback steps.

Integrations

  • Branded PDF quotes with Puppeteer, SMTP email and Telegram notifications
  • A shared, versioned, key-protected read-only content contract for the Tanitio marketing platform; all four sites serve the same contract with their own language profile
  • GA4 and Search Console measurement
  • The “Websites” section of Ensotek's ERP: content management with a site switcher and transfer of web enquiries into the ERP, working through each site's own admin API; technically delivered, with customer acceptance in progress

Today

All four sites are live; each runs independently with its own domain, language and database while drawing on the same core. A fix made in the shared package can be used across the family without being rewritten, while a data or settings change on one site stays on that site. A new site is planned for the ensotek.com domain.