
Subdomain-Based Multi-Tenancy in Nuxt
*By Sean Erick C. Ramones, Vue SME | JavaScript/TypeScript SME*
Sean Erick C. Ramones
What is Multi-Tenancy?
Multi-tenancy is an architecture where a single app instance serves multiple clients (tenants). Each tenant behaves like it has its own isolated version of the app.
Benefits
- Centralized maintenance
- Efficient infrastructure usage
- Per-tenant custom branding
- Easier scaling and onboarding
Subdomain-Based Tenancy in Nuxt
You might have seen urls like this in Jira, Github, Slack, etc. Each tenant accesses the platform via their own subdomain, like:
mllr.preesh.com
acme.preesh.com
some-other-org.preesh.com
Tenant Middleware (Nuxt 3)
// middleware/tenant.ts
export default defineNuxtRouteMiddleware(() => {
const host = useRequestHeaders()['host'] || '';
const [subdomain] = host.split('.');
const knownTenants = useRuntimeConfig().public.knownTenants || [];
if (!knownTenants.includes(subdomain)) return navigateTo('/invalid-tenant');
useState('tenant', () => subdomain);
});
// nuxt.config.ts
export default defineNuxtConfig({
routeRules: {
'/*': { middleware: ['tenant'] },
},
runtimeConfig: {
public: {
knownTenants: ['acme', 'globex']
}
}
});
Custom Branding Per Tenant
We can define per-tenant branding that influences UI themes, logos, and color schemes.
// composables/useTenantConfig.ts
export const useTenantConfig = () => {
const tenant = useState('tenant');
const map = {
acme: { color: '#FF5733', logo: '/acme-logo.svg' },
globex: { color: '#3333FF', logo: '/globex-logo.svg' }
}; // Ideally pulled from a DB or config API
return map[tenant.value];
};
Use this config in layout and theming logic for dynamic styles and assets.
Authentication and Role Management
Suggested Roles
- HR Admin – Full platform access
- Manager – Can send cards to direct reports
- Employee – Read-only access to received cards
Role-Based Access Middleware
// middleware/role.ts
export default defineNuxtRouteMiddleware(() => {
const user = useState('user').value;
if (!user || user.role !== 'HR_ADMIN') return navigateTo('/unauthorized');
});
Security Strategies
To prevent cross-tenant data leakage and protect user data:
- Tenant Isolation: Scope all database queries by
tenant_id - Subdomain Cookies: Use tenant-specific cookies or headers
- Rate Limiting: Apply tenant-specific rate limits
- Session Protection: Do not share session tokens across tenants
Database Schema Design
Each key entity must include a tenant_id to isolate data:
CREATE TABLE users (
id UUID PRIMARY KEY,
tenant_id UUID NOT NULL,
role TEXT
);
CREATE TABLE cards (
id UUID PRIMARY KEY,
tenant_id UUID NOT NULL,
created_by UUID,
message TEXT
);
Deployment Notes
- Set up wildcard DNS:
*.preesh.com - Use platforms like Vercel or Netlify for dynamic subdomain routing
- Automate initial tenant provisioning (branding config, database seeding)
Additional Development Notes
Nuxt Labs recently joined Vercel, which may improve official support for:
- Wildcard subdomain routing
- Scheduled jobs or background workers
- Tenant-based static rendering and caching
While current tenant configs (e.g., themes, logos) are manually defined, a future enhancement could allow tenants to edit their own configuration dynamically. This can be achieved using Nuxt Content as a lightweight CMS for managing per-tenant markdown/config content.
We could also allow tenants to add sub-pages, custom messages, or FAQ sections using markdown files per tenant.
Summary
This multi-tenant Nuxt setup enables Preesh to scale efficiently as a SaaS tool for HR departments, with:
- Per-tenant isolation via subdomains
- Role-based access control
- Custom theming and branding
- Secure and scalable architecture
Future upgrades may include self-service onboarding, tenant CMS integration, and more flexible customization per company.