Skip to content

ADR-0025: Onboarding Subdomain — Two Vite Configs vs Separate Project

  • Status: Accepted
  • Date: 2026-07-13
  • Deciders: User + agent research session
  • Issues: #210

Context

SDD-147 (Q2) specifies that the public onboarding portal (/onboarding/:hash) should be moved to a separate subdomain (onboard.neemias.app) after MVP. Currently the onboarding flow lives at app/src/modules/onboarding/ within the same SPA and bundle.

The onboarding form is a lightweight React + Tailwind app with no dependencies on MUI, recharts, auth contexts, or dashboard code. It calls existing public API routes at api.neemias.app.

Two approaches were considered:

A) Two Vite configs in the same app/ directory — a second config file (vite.onboarding.config.ts) with its own HTML entry, built via vite build --config vite.onboarding.config.ts, output to dist-onboarding/.

B) Separate pnpm workspace projectapps/onboarding/ (or app/onboarding/) with its own package.json, tsconfig.json, vite.config.ts, listed in pnpm-workspace.yaml.

Decision

Approach A: Two Vite configs in the same app/ directory.

Architecture

onboard.neemias.app  ──▶  Cloudflare Pages (build from app/ + vite.onboarding.config.ts)

        └── fetch("/api/v1/onboarding/:hash/*")  ──▶  api.neemias.app (Worker existente)

Key details

AspectChoice
Vite configapp/vite.onboarding.config.ts
HTML entryapp/onboarding-index.html
React entryapp/src/onboarding/main.tsx
Output dirdist-onboarding/
Cloudflare Pages rootapp/
Cloudflare Pages build commandpnpm build:onboarding
Domainonboard.neemias.app

Why not Approach B (separate project)

A separate pnpm workspace package would be the canonical choice in a large, multi-team monorepo using Turborepo conventions (apps/*). However, at Neemias's current scale:

  1. Dependency lists are identical — onboarding uses only React + Tailwind, already in app/package.json. A separate package.json duplicates what's already there.
  2. No net benefit in bundle size — Vite tree-shakes each build independently, so the dist-onboarding/ bundle won't contain MUI or recharts regardless of what's in package.json.
  3. Higher maintenance surface — a separate tsconfig.json, tailwind.config.*, and dev tooling per sub-site must be kept in sync.
  4. Simple upgrade path — if onboarding ever needs its own dependencies or grows to warrant full separation, migration to apps/onboarding/ is a copy-and-register operation.

Cloudflare Pages configuration

SettingMain SPAOnboarding
Project nameneemias-appneemias-onboarding
Root directoryapp/app/
Build commandpnpm buildpnpm build:onboarding
Build outputdistdist-onboarding
Custom domainapp.neemias.apponboard.neemias.app

pnpm-workspace.yaml

No changes needed. Both builds resolve dependencies from the existing "app" workspace entry.

Consequences

  • Positive: Bundle reduction — main SPA no longer includes onboarding components (~8 files, form libraries).
  • Positive: Isolation — onboarding build failures don't block main SPA deploys, and vice versa.
  • Positive: Lower dev overhead — pnpm dev stays unchanged; onboarding dev via pnpm dev:onboarding.
  • Positive: No CORS changes needed — API routes are already public (no auth middleware).
  • Neutral: Two Cloudflare Pages projects to manage instead of one. Build watch paths should be configured to avoid unnecessary rebuilds.
  • Negative: If onboarding later needs different dependencies or build tools, the two-config approach becomes a constraint and full separation will be needed.

Alternatives Considered

AlternativeRejected because
Separate apps/onboarding/ pnpm workspace packageOverhead without benefit at current scale. Documented as the upgrade path.
Single Vite config with rollupOptions.inputProduces a single build with multiple entry points — not deployable to separate subdomains.
Sub-path routing on the same domain (app.neemias.app/onboarding)SDD-147 explicitly specifies a separate subdomain for post-MVP.

Upgrade Path

When onboarding grows to warrant full separation:

  1. Copy vite.onboarding.config.ts into apps/onboarding/vite.config.ts
  2. Create apps/onboarding/package.json with its own dependency list
  3. Create apps/onboarding/tsconfig.json (extends shared base)
  4. Add apps/onboarding to pnpm-workspace.yaml
  5. Move app/src/onboarding/ to apps/onboarding/src/
  6. Update Cloudflare Pages root directory to apps/onboarding/
  7. Remove vite.onboarding.config.ts and onboarding-index.html from app/

References

Distribuído sob licença MIT.