work details

DitcoEU — Multilingual B2B Food and Ingredient Catalogue

A European-market B2B platform combining botanical raw materials, gourmet products, certifications and quotation workflows.

Client

Ditco Food

Start

20 Jul 2026

Completed

DitcoEU — Multilingual B2B Food and Ingredient Catalogue interface and project preview
Description

A European-market B2B platform combining botanical raw materials, gourmet products, certifications and quotation workflows.

Case study

Challenge

Ditco Food's three brands were spread across different sources, and the previous e-commerce platform was built around baskets, stock and prices. The product details, packaging options, certifications and quote requests that European buyers need were not in one place.

Approach

We built the backend and admin panel first, then compiled the catalogue from the three brands' websites and restructured it. The frontend was designed around a group, category and product flow with quote requests instead of prices, and all content was tied to translation tables so German could be added without a schema change.

Outcome

ditcoeu.com is live in German and English on its own infrastructure, with 170 products, certificates and office details managed from the panel. Incoming requests are tracked by status and can be turned into a printable quote document.

Tools

Next.js, React, TypeScript, Fastify, Bun, Drizzle ORM, MySQL

Key Features
  • Three-brand landing: Ditco Ingredients, Pino Roble, Ditco Food

  • Group → category → product catalogue with 170 products

  • Quote request form with product selector instead of prices

  • Status flow, assignment and CSV export for quote requests

  • Sales quote editor with inline line-item editing

  • Token-protected, printable quote document page

  • Certificates: FSSC 22000, BRC, ISO 22000/9001, Halal, Kosher

  • German + English with localised URLs per language

  • All content from the DB: products, banners, team, offices

Technologies Used
  • Next.js

  • React

  • TypeScript

  • Fastify

  • Bun

  • Drizzle ORM

  • MySQL

Design Highlights
  • Three-panel split hero and off-canvas navigation instead of a top menu

  • Colours from a single token set, with two corporate palettes in the panel

  • One consistent 'Request a Quote' call to action instead of prices

  • Missing-translation badges and unsaved-change warnings in the panel

  • An i18n model where a new language needs data, not a schema change

Details

Ditco Food is an Izmir-based food supplier that runs three separate brands: Ditco Ingredients for botanical raw materials, Pino Roble for gourmet products and Ditco Food for professional kitchen products. The company needed a single German- and English-language B2B catalogue for European buyers, one that collects quote requests instead of showing prices and a basket. ditcoeu.com is the catalogue and quotation platform we built from scratch for that purpose, with every piece of content served from the database.

Context and requirements

The previous site ran on an off-the-shelf e-commerce platform that did not fit a B2B sales model. Baskets, stock levels and price fields are not what an importer is looking for; what matters is product information, packaging options, certifications and a quote request that reaches the right person. On top of that, the products of the three brands were scattered across three different sources.

A few decisions were locked in at the start: the site would be a B2B catalogue with no online payment, basket or order flow; every product page would carry a Request a Quote button instead of a price; and none of the products, categories, banners, team or contact details would be hard-coded, everything would come from the admin panel. Adding a new language would not require a schema change.

Solution and scope

A three-brand landing page

The home page opens with a three-panel split hero around a central logo disc. Each panel stands for one brand and takes the visitor straight to that product group's category list. The traditional top menu was removed; navigation runs through a fixed off-canvas menu.

Product catalogue

The catalogue drills down from product group to category to product. The three brands were compiled from their own websites and restructured; the catalogue currently holds 170 products. Product pages bring together an image gallery, variant and packaging options, technical specifications and breadcrumbs, and category cards are shown with cover images.

Quote requests

On the quote form, visitors pick products from a selector; arriving from a product page pre-selects that product. The form captures B2B fields such as company name, contact person, email, country and requested quantity, makes privacy consent mandatory and uses a hidden honeypot field against bots. A single request can contain up to 50 line items.

Corporate pages

About Us, Our Team, Certificates and Contact were redesigned. The certificates page presents FSSC 22000, BRC Global Standard, ISO 22000, ISO 9001, Halal and Kosher with their real logos and a document gallery. The contact page shows office addresses, a world-map banner and two separate forms. Privacy, terms of use and cookie policy pages are also managed from the panel.

Admin panel

The project was planned so that the backend and admin panel were finished before the frontend. The panel manages:

  • Product groups and categories: parent selection, filtering by group and ordering; group banners are picked from the media library.
  • Products: language tabs, variants and packaging, multiple images and technical specifications, with a badge on any language tab that is missing a translation.
  • Quote requests: a status flow (new, in review, contacted, qualified, closed, spam), assignment, internal notes, quick email/phone/WhatsApp actions and CSV export.
  • Sales quotes: a quote editor with inline line-item editing, automatic quote numbers, revision and dispatch logs, plus a printable quote document link for the customer.
  • Customers: creating customer records from quotes and viewing their history.
  • Team and offices: multilingual records with ordering.
  • Site settings and theme: colour palette, logo, favicon, social links and legal pages.

Forms warn about unsaved changes, lock against double submission and ask for confirmation before deleting.

Technical architecture

The frontend is built with Next.js 16 and React 19, the admin panel is a separate Next.js app, and the API runs on Fastify on Bun. The data layer is MySQL with Drizzle ORM; the catalogue has dedicated tables for products, product translations, variants, images, specifications, offices, team members and quote request items. Every content table has a translation table, which is why German could be added later without touching the schema, only the data.

Active languages are read from a database setting. German is the default, URLs are localised per language and the slug changes along with the language. If an unsupported language is requested, the API returns an explicit error rather than silently falling back. Public catalogue responses are cached briefly; admin responses are never cached.

On the SEO side, the site ships Organization structured data, a dynamic sitemap, robots rules, an llms.txt file and an IndexNow key. Design colours come from a single token set, and two ready-made palettes, corporate green and petrol, can be switched from the panel. Secret keys are configured so that the application refuses to start without them.

Integrations

The admin panel includes Google account connection (Gmail and Calendar), Search Console, GA4 and Google Ads screens. Quote documents are generated as token-protected pages that can be printed straight from the browser. The site runs on its own VPS with PM2 and Nginx, behind Cloudflare with SSL.

Outcome

Ditco Food now presents all three brands under one domain, in German and English, structured the way a B2B buyer expects. Adding a product, updating a certificate or turning an incoming request into a quote no longer requires a developer; it is all done in the panel. Quote PDFs and automatic quote emails have been scheduled for a second phase.