Live

A webshop in eight languages that enforces its promises in code

Riha is the hijab line of alsouq.nl, a modest fashion webshop for the Netherlands and the EU, built on Medusa 2.0 with a custom Next.js storefront and payments through Mollie.

Role
Everything, built alone
Period
May 2026 to now
Stack
TypeScript, Medusa 2, PostgreSQL, Next.js, next-intl, Mollie, Docker
Status
Live
alsouq.nl · home
Home page of alsouq.nl on a laptop
The same home page on a phone
The live shop, captured on 27-10-2026.

The problem

The audience, Muslim women in the Netherlands and the rest of the EU, knows the big brands and drops out at cheap-looking shops that promise more than they deliver.

What I built

A brand shop on a headless Medusa 2.0 backend with its own workflows and its own module, and a custom-built Next.js storefront instead of the standard starter. Shipping to 25 EU member states with one VAT-inclusive price per country.

Legal and commercial rules, such as VAT territories, discount promises and colour claims, are fixed in code and tests instead of as text on a page.

What matters technically

  1. Checkout refuses ten territories

    Territories such as the Canary Islands and Åland belong to an EU country but fall outside the VAT area: the VAT-inclusive price is wrong there. The shop refuses checkout there when the cart is created, updated and completed, even when an address arrives in parts.

  2. An email change that cannot half succeed

    Changing the login address is a workflow with compensation. Only the hash of the token is stored and the token is used up before the account moves, so two clicks on the same link cannot both succeed. If something fails further on, the customer gets the token back.

  3. Eight languages, Arabic right to left

    Dutch, English, Arabic, French, German, Swedish, Spanish and Italian. The code keeps three ideas apart: the default language, the source language of the catalogue and the legally binding language for terms and privacy.

  4. Colour claims with evidence

    Every colour in the catalogue carries a kind of evidence: measured from a product photo, dyed by the shop itself or only a printed name. A colour that is really sold may not rest on a name alone, and a test makes sure the list of exceptions can only shrink.

  5. Shop configuration as code

    Regions, VAT, stock location and shipping options live in one script that brings the database to that state on every run, with its own integration tests. Nothing is clicked together by hand in an admin.

  6. A welcome discount that fails closed

    The welcome offer mirrors exactly one real promotion in the backend. If a value is missing or expired, the shop shows nothing: announcing a discount the checkout refuses is a misleading commercial practice under Dutch law (art. 6:193c BW).

Measured

Counted in the repository, not estimated. The number of delivery countries comes from the deploy documentation.

languages, Arabic among them
8
EU member states delivered to
25
territories excluded at checkout
10
pages in the storefront
33
test files
26
How measured
storefront/src/i18n/config.ts
docs/DEPLOY-STATE.md
EXCLUDED_TERRITORIES in backend/src/lib/excluded-territories.ts
git ls-files 'storefront/src/app/*page.tsx' | wc -l
git ls-files | grep -E '\.(test|spec)\.tsx?$' | wc -l

Measured on 27-10-2026 in the project's own repository.

Need something similar, or a team that builds systems like this?

info@bitvire.com