Docs LATEST

Modules Configuration

Discovery paths, explicit registrations, and tenant-aware module scanning.

Configuration

config/modules.php defines where Core should look for modules and how tenant-aware discovery should behave.

Default configuration #

return [
    'paths' => [
        base_path('user/modules/*'),
        base_path('../VelvetCMS*'),
    ],
    'tenant_paths' => [
        base_path('user/tenants/{tenant}/modules/*'),
    ],
    'modules' => [],
    'auto_discover' => true,
];

Keys #

Key Description
paths Directories or glob patterns used for module discovery
tenant_paths Tenant-scoped module paths that support the {tenant} placeholder
modules Explicit module entries where the key is the module name
auto_discover Enable discovery from configured paths and Composer packages

Behavior #

  • paths supports plain directories and glob patterns.
  • tenant_paths is only used when tenancy is enabled and a tenant id is resolved.
  • modules is for explicit entries when a module lives outside the usual scan paths.
  • Composer packages of type velvetcms-module are included when auto-discovery is enabled.

Core does not load directly from these paths on every request. The module toolchain compiles discovered manifests into runtime artifacts, and the app boots from those compiled results.

Explicit modules #

'modules' => [
    'docs' => '../VelvetCMS-Docs',
],

If the configured path points to a module root, Core expects module.json inside that directory.

Tenant paths #

tenant_paths uses a {tenant} placeholder. At runtime, Core substitutes the active tenant id and scans the resulting path.

'tenant_paths' => [
    base_path('user/tenants/{tenant}/modules/*'),
],

That lets you keep tenant-local modules physically separate from globally shared modules.

Notes since the 2.1 module refresh #

  • The default external glob is ../VelvetCMS*, not the older ../VelvetCMS-* pattern.
  • Declarative module commands, auto-registered views, and auto-loaded routes all depend on successful compilation.
  • Module config files are namespaced automatically. Access them with namespace:file.key syntax.

See Modules for manifest structure and convention-based auto-loading.