Modules

Platform layers

Edit page
Understand the reusable foundation packages, their ownership boundaries, and host-owned presentation.

Nuxt Customer Portal follows Nuxt's npm-layer model. Each layer package exposes nuxt.config.ts, declares a stable $meta.name, and is composed through extends. The preset provides a useful starting point without owning the host's brand or public website.

Layer catalog

PackageOwns
coreSessions, Better Auth infrastructure, tenancy, authorization, database access, feature registry, shared contracts, and generic OpenAPI merging
uiNeutral shell primitives, contribution rendering, and fallback layouts
authenticationLogin, signup, email verification, and password recovery UI
organizationsProfile, organization selection, invitations, settings, and email-provider credentials
administrationInstallation-wide organization and user administration
presetComposition of core, UI, authentication, organizations, and administration
kitPortal configuration, diagnostics, provider resolution, migrations, and legacy adoption

service-requests and timesheets are optional business packages. A host selects either, both, or neither in portal.config.ts.

Core and UI

core is visually headless. It must not render a branded application shell or import an optional business package. Feature code consumes @nuxt-customer-portal/core/feature, @nuxt-customer-portal/core/server, and @nuxt-customer-portal/core/schema.

ui turns serializable feature registrations into neutral navigation, dashboards, surfaces, modals, and fallback layouts. A production host can override those layouts and compose the same primitives differently. The Apex and Brutal demos prove this by sharing package selection but not demo-only shell components.

Open the core and UI contracts

Authentication and organizations

authentication owns account entry and recovery screens while core retains Better Auth configuration and identity records. organizations owns the signed-in user's profile, organization selection, invitations, and tenant settings. Neither grants installation-wide administration privileges.

Server operations always derive the active organization from the authenticated session. Organization identifiers supplied by the browser are not trusted when session context determines the tenant.

Administration and surfaces

administration owns system-administrator routes and APIs. Optional features must not be imported by administration to add feature-specific panels. Instead they register a PortalSurfaceContribution for a named surface such as administration.organization.detail; the UI resolves the component only when that package is installed.

Preset and kit

Use @nuxt-customer-portal/preset for the common platform. Add business packages independently. The kit converts portal.config.ts to Nuxt extends, resolves official and local manifests, checks dependency order, and manages one immutable migration stream per provider.

Public pages, branding, app.vue, layouts, headers, footers, error pages, assets, and global styling are host-owned. They intentionally have no public-site package.

Decide where a change belongs

  1. Shared sessions, tenancy, authorization, database, registry, or contracts belong in core.
  2. Reusable presentation and fallback shells belong in UI.
  3. Account entry belongs in authentication.
  4. Profile and tenant management belong in organizations.
  5. Installation-wide management belongs in administration.
  6. Optional domain workflows belong in their own package.
  7. Brand and marketing experiences belong in a host app.

If a change crosses boundaries, add the smallest serializable contract or surface registration instead of a private physical import. Continue with Create a feature layer or inspect the product source map.