Skip to content
Agentmart
Submit a tool

multitenant

Multi-tenant / multitenancy patterns in Vovk.ts — hosting multiple tenants from one Next.js app via subdomain routing.

Skill by finom

IndexedMIT★ 54
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/finom-multitenant

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Multi-tenant / multitenancy patterns in Vovk.ts — hosting multiple tenants from one Next.js app via subdomain routing. Covers the `multitenant()` helper from `vovk`, the Next.js `proxy.ts` file that wires it up, the `overrides` shape (static / dynamic / nested subdomain patterns), the `vovk.config.mjs` changes needed (switch to segmented client, `segmentNameOverride`), per-tenant frontend page routes, wildcard DNS, and local subdomains under `localhost`. Triggers on phrasings like "multi-tenant", "multitenancy", "per-tenant API", "per-tenant frontend", "host `admin.example.com`", "serve per subdomain", "tenant per customer", "wildcard subdomains", "route subdomain to segment". Does NOT cover creating or configuring an individual segment — hand off to the `segment` skill. Does NOT cover writing controllers inside a tenant segment — hand off to the `procedure` skill. Does NOT cover composed-vs-segmented client specifics beyond the flip — hand off to the `rpc` skill.

Use cases: frontend, backend, writing

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/multitenant

What's inside

Skill name
multitenant
Description
Multi-tenant / multitenancy patterns in Vovk.ts — hosting multiple tenants from one Next.js app via subdomain routing. Covers the `multitenant()` helper from `vovk`, the Next.js `proxy.ts` file that wires it up, the `overrides` shape (static / dynamic / nested subdomain patterns), the `vovk.config.mjs` changes needed (switch to segmented client, `segmentNameOverride`), per-tenant frontend page routes, wildcard DNS, and local subdomains under `localhost`. Triggers on phrasings like "multi-tenant", "multitenancy", "per-tenant API", "per-tenant frontend", "host `admin.example.com`", "serve per subdomain", "tenant per customer", "wildcard subdomains", "route subdomain to segment". Does NOT cover creating or configuring an individual segment — hand off to the `segment` skill. Does NOT cover writing controllers inside a tenant segment — hand off to the `procedure` skill. Does NOT cover composed-vs-segmented client specifics beyond the flip — hand off to the `rpc` skill.
License
MIT
Instructions
241 lines in SKILL.md · view on GitHub

Before installing

  • Instructions call the network

Files (1)

  • SKILL.md

SKILL.md (first lines)

# Vovk.ts multi-tenant routing

Host multiple tenants from one Next.js app. Each tenant gets own **named segment** on backend, own **frontend page route** on frontend, wired together with subdomain-aware **proxy** calling `multitenant()` from `vovk`.

Typical shape:

- `example.com/` → root tenant (marketing home, or tenant picker).
- `admin.example.com/` → admin tenant — internal backend + UI.
- `customer.example.com/` → customer-facing portal (signup, landing, etc.).
- `<customer>.customer.example.com/` → per-customer instance.
- `pro.<customer>.customer.example.com/` → per-customer pro tier.

Pick any shape; this skill shows wiring for any.

## Architecture

Three layers, one request:

1. **Proxy (`src/proxy.ts`)** — intercepts every request, calls `multitenant()` with incoming URL, host, your `overrides` map, gets back `{ action, destination }`. Branches into `NextResponse.rewrite`, `NextResponse.redirect`, or 404.
2. **Named segment per tenant** on backend (`src/app/api/admin/[[...vovk]]/route.ts`, etc.). Each tenant's `api/*` calls land here after proxy rewrite.
3. **Per-tenant frontend page routes** on frontend (`src/app/admin/page.tsx`, etc.). Each tenant's non-api requests land here after proxy rewrite.

Proxy **rewrites** — does NOT redirect (except reserved-path guard, see below) — so `admin.example.com/` stays in user's address bar while Next.js internally serves `src/app/admin/page.tsx`.

## 1. Create a segment per tenant

```bash
npx vovk new segment admin
npx vovk new segment customer
npx vovk new segment customer/pro
```

Controllers go in `src/modules/...` as usual. See **`segment` skill** for segment shapes, `initSegment()`, nested paths; see **`procedure`** for controller authoring.

## 2. Switch to segmented client and override segment names

In `vovk.config.mjs`:

```js
/** @type {import('vovk').VovkConfig} */
const config = {
  composedClient: { enabled: false },
  segmentedClient: { enabled: true },
  outputConfig: {
    segments: {
      admin:          { segmentNameOverride: '' },
      customer:       { segmentNameOverride: '' },
      'customer/pro': { segmentNameOverride: '' },
    },
  },
};

export default config;
```

Why:

- `composedClient.enabled: false` + `segmentedClient.enabled: true` — switches from single all-segments RPC bundle to one client per segment. Each tenant's frontend imports only RPC it uses → lean bundles.
- `segmentNameOverride: ''` per tenant — leaves the segment name out of the URLs that segment's client calls (`/api/users`, not `/api/admin/users`), so the proxy's `{ from: 'api', to: 'api/<tenant>' }` rewrite routes them to the tenant's segment. The client folder keeps the segment name: `admin` pages import `@/client/admin`.

See **`rpc` skill** for full segmented-client reference.

## 3. Wire the proxy

`src/proxy.ts` (or `proxy.ts` at project root if `src/` not used):

```ts
import { NextRequest, NextResponse } from 'next/server';
import { multitenant } from 'vovk';

export default function proxy(request: NextRequest) {
  const { action, destination } = multitenant({
    requestUrl: request.url,
    requestHost: request.headers.get('host') ?? '',
    targetHost: process.env.VERCEL ? 'example.com' : 'localhost:3000',
    overrides: {
      admin: [
        { from: 'api', to: 'api/admin' },
        { from: '',    to: 'admin' },
      ],
      customer: [
        { from: 'api', to: 'api/customer' },
        { from: '',    to: 'customer' },
      ],
      '[customer_name].customer': [
        { from: 'api', to: 'api/customer' },
        { from: '',    to: 'customer/[customer_name]' },
      ],
      'pro.[customer_name].customer': [
        { from: 'api', to: 'api/customer/pro' },
        { from: '',    to: 'customer/[customer_name]/pro' },
      ],
    },
  });

  if (action === 'rewrite' && destination) return NextResponse.rewrite(new URL(destination));
  if (action === 'redirect' && destination) return NextResponse.redirect(new URL(destination));
  return NextResponse.next();
}

export const config = {
  matcher: ['/((?!static|.*\\.png|.*\\.svg|.*\\.ico|.well-known|_next/image|_next/static).*)'],
};
```

`targetHost` is your root domain — branch on `process.env.VERCEL` (or your own flag) so local dev uses `localhost:3000`, prod uses real hostname.

## 4. Per-tenant frontend pages

Each tenant override maps `from: ''` → `to: '<tenant>'`. Non-api requests to tenant subdomain rewrite to `/<tenant>` internally; Next.js serves from `src/app/<tenant>/page.tsx`.

File tree mirroring proxy example above:

```
src/app/
  page.tsx                                    ← root tenant (example.com/)
  admin/page.tsx                              ← admin tenant (admin.example.com/)
  customer/page.tsx                           ← customer landing (customer.example.com/)
  customer/[customer_name]/page.tsx           ← per-customer instance (<name>.customer.example.com/)

From finom/vovk, MIT.

More from finom/vovk

Signals

Stars
54
Forks
0
Open issues
0
Last commit (this folder)
Oct 13, 2026 (14 days ago)
Last release
Oct 22, 2026 (5 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
Website
vovk.dev
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from finom

Cite this page

multitenant skill. Agent Mart. https://agentmart.dev/skills/finom-multitenant (last updated 2026-10-24)