Modules

Switch on what the client needs. Nothing else.

Every site starts as pages, media and forms. Eighteen modules flip on per tenant, from one toggle. A module that is off ships nothing at all: no admin tab, no routes, no JavaScript, no cron work. The same theme serves a brochure site and a webshop.

Toggle per tenant

Eighteen modules, one platform.

Blog

01

Articles and tags with scheduled publishing: set a publish date in the future and the post stays invisible until it passes. Per-locale translations, an RSS feed, tag archives and automatic "read next" from shared tags.

No dependencies

Catalog

02

Products, categories, tags and tax classes, with variants when you need them: option types like size and colour produce per-variant SKU, price, stock and weight. Search page included. Useful on its own for a "featured work" grid, without any shop.

No dependencies

Customer

03

Registration with email verification, login with remember-me, password reset, and an account with profile, address book and past orders with their invoices. A business customer keeps a company name and VAT number on the account. Every screen and every mail is a template your theme can override.

No dependencies

Cart

04

Anonymous and persistent carts. Each line snapshots the name and price at the moment it was added, so editing a price never rewrites somebody's open cart. Products can ask for a note per line: the text to engrave, the allergy to avoid.

Needs catalog + customer

Checkout

05

Address and payment picker, cash on delivery, Mollie and Stripe with verified webhooks, receipt to the customer and a notice to your inbox. Numbered PDF invoices and credit notes, a morning's packing slips in one print, and a holiday closure that keeps the shop selling.

Needs cart + catalog + customer

Shipping

06

Carriers, zones and rate tables. A zone is a set of countries, optionally narrowed to postcode ranges, prefixes or exact codes, and rates go by weight and package size. Two carriers in one zone means the customer picks; cheapest is offered first.

Needs checkout

Vouchers

07

Promo codes: percentage, fixed amount, free shipping, or buy-X-get-Y over the cheapest qualifying units. Validity window, minimum order and a hard redemption cap that is counted once, on the order that actually gets paid, and frozen onto it.

Needs cart

Catalog & volume discounts

08

Automatic repricing with no code typed. A sale on one product or a whole category, or quantity tiers where reaching 10 reprices the entire line, not just the units past the break. Shelf, cart and till all read the same resolver.

Needs catalog

Gift cards

09

Sold as a product, one variant per amount, and mailed to the person it is for on the day the buyer picked. The code exists only once the order is paid. It is spent as a balance: a €50 card against a €30 order leaves €20 for next time.

Needs cart

Landing pages

10

One template plus a CSV is N published pages: five services across nine cities is 45 URLs, each with its own slug and meta pattern. The import validates every row, slug clash included, before it writes anything.

No dependencies

Portfolio

11

Collections backed by a media folder. Dropping a photo in the folder adds it to the gallery, and the folder order is the gallery order. Deep-linkable tabs with arrow-key navigation, and every panel stays visible when JavaScript does not load.

No dependencies

Newsletter

12

Double opt-in capture and campaigns that send in batches of 50 with a pause between, because a burst tanks deliverability for the whole domain. One-click unsubscribe from the mail client, which is what keeps you out of spam folders.

No dependencies

Review requests

13

Some days after an order ships, the customer gets one email asking for a review on your Google profile, or on any review site you name. bol.com orders, refunds and anyone who unsubscribed are skipped, and a returning customer is not asked again for months.

Needs checkout

Vehicle lookup

14

A Dutch plate becomes brand, model and year on a quote form, free through the RDW open register, cached per site. When the registry cannot answer, the field is a plain text input and the visitor still submits.

No dependencies

FAQ

15

Questions as rows, not paragraphs. Optional categories with a page each, a search box that works without JavaScript, and a link straight to any one answer. Each language keeps its own list, and the FAQPage data describes exactly what is on the page.

No dependencies

SEO

16

Title, description, canonical, Open Graph, JSON-LD and hreflang, editable next to the page copy, plus sitemap.xml and llms.txt. On for every site from day one. Switch it off and the head is the bare title; switch it back and every stored override returns.

On by default

VAT engine

17

VAT by destination for the Netherlands and Belgium, VAT on shipping, and 0% for EU businesses whose number checks out in VIES. The quarterly return figures and proof of transport sit on one screen. An order it cannot decide is refused, never guessed.

Needs checkout

bol.com

18

Stock goes up to your bol offers and orders come down as ordinary orders, every fifteen minutes. It never creates an offer or pushes a price, and an imported order keeps what the customer paid on bol. A dry run shows the changes first.

Needs checkout

A module that depends on another stays off until that one is on too, and the admin says which is missing rather than half-working.

From brochure to webshop

A shop is four toggles, not a rebuild.

Enable in dependency order and the site grows a catalogue, accounts, a cart and a checkout. The pages, the theme and the URLs the client already has stay exactly as they are.

01

Catalog

Products, categories, tax classes, variants.

02

Customer

Accounts, verification, address book.

03

Cart

Lines that snapshot price and name at add.

04

Checkout

COD, Mollie, Stripe, receipts, invoices.

Deliver where you actually go

A caterer with one van serves postcodes, not countries. Zones take ranges, prefixes and exact codes, and the postcode zone beats the country-wide one. Switch on "only accept orders we can deliver" and an out-of-area order is refused at checkout by name, instead of arriving and needing a phone call back.

Two kinds of discount, stacked

Vouchers are typed in: percentage, fixed, free shipping or buy-two-get-one on the cheapest qualifying unit, with a cap that cannot oversell even under a re-delivered webhook. Catalog rules need no code at all: a category on sale, or a volume tier where buying 10 reprices the whole line.

Sell on bol.com from the same stock

Stock goes up to your bol offers, orders come down as ordinary orders you fulfil next to your own, every fifteen minutes. Your listings and your bol prices stay yours: the sync never creates an offer and never pushes a price. A dry run shows exactly what a real sync would change, having written nothing.

Closed for the holidays, still selling

Enter the days nobody is there to post parcels and checkout stays open throughout. From two weeks ahead, or whatever lead time suits the shop, the cart and checkout tell every customer in their own language the day their parcel leaves, so nobody pays without having read it. An editor sets it, without an admin account.

A gift card is money, not a discount

A voucher lowers what an order costs. A gift card pays for it: the total, the revenue and the VAT stay what they are, and the card comes off the amount the customer is charged. Several cards on one cart are spent smallest first, and an order a card covers in full never goes to the payment provider.

Reviews asked for once, and by the rules

Every customer gets the same link with nothing offered in return, because Google removes reviews that were filtered or paid for. Each order is asked at most once, an order more than a week overdue is let go so switching it on never mails your whole history, and every request is on the order next to its other mails.

No toggle needed

And this is on every site, from day one.

Forms that survive the internet

Six layers on every submission: per-IP and per-form rate limits, an HMAC-signed field schema, a three-second time gate, CSRF, a honeypot, and content scoring for the human-written junk that clears all five. Spam is quarantined for review, never bounced, so a false positive never tips off a spammer.

Attachments without an inbox full of zips

A form can take files. They are stored by content hash, and the notification mail lists them with one signed link to the submission, where they preview and download one by one or as a ZIP. The link expires within 30 days. Type is checked on the file's magic bytes, so a renamed executable is refused whatever the extension says.

Upload a video, get a player

Anything you upload is converted to MP4, given a poster frame and downscaled copies, and rearranged so it starts before it has finished downloading. The player picks a size per screen and connection, and a phone can be given a still image instead of the loop entirely.

Images that do not wreck the layout

Images resize on request and are served as WebP where the browser says it can take them, with width and height in the markup so nothing jumps as the page loads. Everything below the fold loads lazily, and the theme marks what sits above it, so the first slide of a carousel arrives at once.

Second language, not second site

A translation is a language tab on the page you already have, so template, structure and parent stay in step. An untranslated page falls back to the default language instead of 404ing, and only genuinely translated locales are offered in the switcher and in hreflang.

Hidden until you launch

A new site starts behind a coming-soon page for everyone not on your list, and hidden from search engines in the meta tag, the header and robots.txt, until you deliberately go live. That switch does not hang on the SEO module: turning SEO off stops helping crawlers, it never lets them in early.

Cookie wall and honest statistics

Accept or reject, remembered twelve months, in eleven languages, following the visitor's locale. Bump the policy version and everybody is asked again. Statistics are first-party: server-side pageviews plus time on page, scroll depth and outbound clicks, with identifying cookies minted only after consent.

Reviews, straight from Google

Set the Place ID and the daily sync mirrors the reviews locally. The widget renders from that mirror, never from a live API call at render time, so a rating badge in the header costs nothing and cannot slow a page down. With Review requests on, your customers are asked for new ones.

Backups, quotas and who did what

Snapshot and restore a tenant's content on its own. Storage is broken out per site: media, renditions, backups, attachments and every deployed theme version. An editor works in every module the site has on; settings, payment providers and users stay with an admin. Login takes a passkey, and acting as another user is written to the audit log.

Contact details, entered once

Phone, e-mail, address, KvK, VAT number and social profiles live on the website, not on a page. Every page and the Organization data search engines read show the same values, and changing the number needs no deploy.

A WhatsApp button you can steer

Switch it on, pick the number, write an opening message and a label per language, and choose which countries see it. Pages stay cached: the country check runs in the browser, so nobody outside the list gets the button.

Before and after, dragged

A compare field puts two photos in one frame with a divider the visitor drags: the mossy roof and the clean one. It starts where the editor left it and still works, keyboard included, when JavaScript does not load.

Not sure which of these your clients need?

Send us two of your existing sites. We mirror them into a sandbox tenant with the modules they would actually use switched on, and you click around in it for half an hour.