Six domains, two hosting stacks. Each domain does one thing for one audience. This page explains what lives where, how we set it up, and why the stack is split this way.
Main brand. Services, consultancy, building, innovation. This is where we brand. The story for the SMB decision-maker who finds us via Google: what we build, who for, and how to install something today.
Platform proposition. ConNext as a product. For the government and SMB decision-maker who wants to see the system level: app ecosystem, workspace + apps, "what is ConNext".
Per product. One subdomain per app: opencatalogi, openregister, docudesk, launchpad, openconnector, and the rest. For the user and developer who wants to work with that specific app. Docs, API, install link.
App store. Our own catalogue. Built on OpenCatalogi, because we dogfood our own product. Externally linked from every other site, because this is where the "install now" button lives.
Hosting proposition. For customers who want their own Nextcloud environment, managed by us. Apex domain, so its own GitHub Pages repo with its own CNAME. Brand colour is Common Ground yellow, not cobalt: this is the Common Ground branch, not the Conduction one.
Customer environment. Real Nextcloud instances per customer. No GitHub Pages, no static build. Live application with data, users, integrations. This is the working software, not the proposition.
Rendered with <cn-domain-tree> + <cn-hex>.
For anything that's marketing or docs content. Static, version-controlled, deployable via a GitHub Actions workflow. One repo per subdomain, because GitHub Pages binds one custom domain per repo.
connext repo for connext.conduction.nl, opencatalogi repo for opencatalogi.conduction.nl, and so on.@conduction/docusaurus-preset. One npm package with the brand tokens, theme, navbar, footer. Every site imports it; visual consistency without a monorepo.static/CNAME. GitHub reads it on every deploy.main builds and publishes to gh-pages. Live within one or two minutes.For anything that's CMS content, or an actual product. We dogfood our own apps: the main brand and the app store run on OpenCatalogi; customer environments run on stock Nextcloud.
[client].commonground.nu is a working Nextcloud instance per customer, with their own data and users. No marketing layer.Docusaurus 3 supports multilingual sites natively. One build generates all four languages into the same build/ output. Dutch is the default and lives at the root; the other languages get a sub-path: /en/, /de/, /fr/. Marketing copy and docs are always available in four languages without separate deploys.
/, the cleanest URL, matches "we lead in NL".themeConfig.navbar.items.<link rel="alternate"> per language, on every page, no config required.Translations live in i18n/<locale>/ per site. Markdown files go into i18n/de/docusaurus-plugin-content-docs/current/; UI strings into code.json. If a translation is missing, Docusaurus falls back to the defaultLocale. Pages stay findable; the fallback isn't a 404.
npm run write-translations to a CI check so missing keys break PRs, not production.
Configuration lives in @conduction/docusaurus-preset. One i18n block there, all five or six sites stay in lockstep. Template settings for the preset:
// docusaurus.config.js i18n: { defaultLocale: 'nl', locales: ['nl', 'en', 'de', 'fr'], localeConfigs: { nl: { label: 'Nederlands', htmlLang: 'nl-NL' }, en: { label: 'English', htmlLang: 'en-GB' }, de: { label: 'Deutsch', htmlLang: 'de-DE' }, fr: { label: 'Français', htmlLang: 'fr-FR' }, }, }, trailingSlash: true,
Source: Docusaurus i18n introduction · i18n tutorial
GitHub Pages binds exactly one custom domain to each repo, via the CNAME file at the root. Wildcards (*.conduction.nl) are explicitly discouraged by GitHub because of domain-takeover risk. One Docusaurus build can't serve multiple subdomains.
That could turn into a messy pile of repos. Which is why they all share the @conduction/docusaurus-preset package. Brand tokens, navbar, footer, theme: everything comes from one place. Fix a design bug in the preset once, every site benefits on the next build.
The CMS route via OpenCatalogi doesn't have that restriction: one Nextcloud instance serves all of its own content. But that only applies where we actually do CMS work. Docs and marketing content stay static, because static is faster, cheaper, and more reliable. GitHub Pages docs.
Create a new repo under ConductionNL/. Scaffold a Docusaurus site with npx create-docusaurus@latest. Add static/CNAME with your subdomain: new.conduction.nl.
Install @conduction/docusaurus-preset and wire it into docusaurus.config.js. Brand, colours, and typography work immediately. Add the A record on DNS to the GitHub Pages IPs.
The preset ships the i18n block (nl/en/de/fr). Translate NL first, then the rest in i18n/<locale>/. Run npm run write-translations -- --locale <x> to generate UI strings.
Add .github/workflows/deploy.yml (publishes to gh-pages). Set GitHub Pages in repo settings to that branch. The apex domain is already verified at org level; DNS checks work immediately.