Skip to content

Modules ​

Evolve ships as one Composer package, racerfish/evolve. The core is always on: pages, blocks, media, navigation, forms, settings and the panel itself. Everything else is a module: a directory in the package with its own service provider, configuration, migrations, panel screens, frontend routes and blocks. A project does not install modules, it switches them on and off.

The modules in 2.16 ​

ModuleKeyDefaultAdds
Blogblogonposts and categories, a posts block, news detail pages
Companycompanyonmembers, teams and jobs, three blocks, JobPosting structured data
Eventseventonevents with registration, participants and ICS download
FAQfaqonquestions with categories and a FAQ block
Locatorlocatoronlocations and regions, a store finder block and a map block
Projectsprojectonprojects with categories and detail pages
Scout24scout24onAutoScout24 vehicle listings, marketplace and search blocks
Shopifyshopifyonproducts, collections, cart and checkout against Shopify stores
Email campaignsemailoff (since 2.22)newsletter campaigns with a Brevo push and the Brevo contact sync; the mail templates for form mails are core
MCP Servermcponan MCP server for AI clients, stdio and HTTP
AI chatbotai-chatbotoffa chatbot on the site, built on laravel/ai
Regionsregionoffcountry-based content variants (a core feature behind a module switch)
Media Governancemedia-governanceoffapproval workflow, rights levels and IPTC prefill for the media library (2.22)
Devtoolsdevtoolsondeveloper tools, the logs disk for the log viewer

"Default" is the value in the package's core/config/evolve.php. A project that published config/evolve.php can differ, check the project file.

Switching a module on or off ​

A module's switch is evolve.modules.<key>. Three places set it, the first that applies wins:

  1. The .env. EVOLVE_MODULE_<KEY>=true or false. The key is upper case, hyphens become underscores: EVOLVE_MODULE_AI_CHATBOT=true. Since 2.21 this works for every installed module, also one the project's config/evolve.php does not list. The module switches in the panel's Developers tab (Settings, visible to the developer role) write exactly these variables, so an edit in the panel and an edit in the file are the same thing.
  2. The project's config/evolve.php, if it was published, under modules.
  3. The default. Without a published config/evolve.php, the table above. A published file replaces the package's modules list as a whole, so a module missing from it falls back to the module's own default, which can differ from the table (MCP is off by its own default).

A module that runs on its default changes with the default. The module_switches health check (2.21) names every module nothing switches; set those switches explicitly, in the .env or in the Developers tab. New installs get every switch written into the .env by php artisan evolve:install. The email default changed in 2.22: the module is off unless a switch turns it on, because its form mail templates became part of the core. Sites with newsletters or the contact sync set EVOLVE_MODULE_EMAIL=true.

The switches are applied while the configuration is built, so they are part of a cached config. After changing a switch in a server .env by hand, rebuild the cache with php artisan config:cache, which the deploy does anyway. The panel rebuilds it when you save.

The Developers tab of Settings: environment type, debug, banner, mail safety; the module switches follow further down

What happens when a module is off ​

The module's service provider returns before it registers anything. There is no config merge, no migrations, no routes, no panel entry, no Livewire components and no blocks. The module's database tables stay as they are, so switching a module off and on again loses nothing. Two consequences to know:

  • A page that contains one of the module's blocks renders an evolve:missing-block HTML comment in place of the block (since 2.6). In local development the block reports itself as missing.
  • The module's migrations only load while the module is on. After enabling a module for the first time on an environment, run php artisan migrate (the deploy does this).

Modules with requirements ​

The MCP server needs laravel/mcp, the AI chatbot needs laravel/ai. Evolve suggests both packages but does not require them (since 2.21), so a project that uses one of these modules requires its package itself, for example composer require laravel/mcp. When the package is missing, the module stays off even if its switch is on. The health endpoint then reports it with active: false and the missing package, and the module switches health check warns until the package is installed or the module is switched off. Scout24, Shopify and the locator need vendor credentials, see their pages.

Who can open a module ​

Every panel route a module registers runs behind the role middleware, with the roles from evolve.roles.modules.<key>. Without an entry, evolve.roles.modules.* applies; without that, every logged-in panel user can open the module. The sidebar hides what a user cannot open. The lists are project code in config/evolve.php, not .env variables. Roles has the resolution rules and a worked example.

What a module brings to the panel ​

When a module registers itself, the panel gains:

  • a sidebar entry and its screens under /evolve/<key>/...;
  • Cmd-K commands for its views and for creating a record, in the command palette (since 2.15);
  • its models in the global search, where the module declares them searchable;
  • its settings in the Settings screen, for example BLOG_OVERVIEW_PAGE or SCOUT24_MEMBER_ID. These are plain .env keys the panel edits for you, not database settings;
  • its translations for the frontend.

Blocks, list pages and detail pages ​

Modules bring content to the site in three ways.

Blocks. A module's blocks (for example the posts block or the store finder) appear in the block picker as soon as the module is on, and they render from the module's own views without a vendor:publish (since 2.6). Publish the views only to change them.

Detail pages. Records such as posts, members, events, projects and vehicles are routeable: each gets a URL under the module's prefix, /{locale}/news/{slug} for a post or /{locale}/project/{slug} for a project. Some modules let a project switch detail pages off (EVENT_ALLOW_ROUTEABLE, PROJECT_ALLOW_ROUTEABLE), and some ship with them off (company members, FAQs, locations).

List pages and the overview page setting. Most modules have a built-in list route such as /{locale}/blog. The usual setup is different: you create a CMS page, place the module's list block on it, and point the module to that page with its overview page setting (BLOG_OVERVIEW_PAGE, PROJECT_OVERVIEW_PAGE, FAQ_OVERVIEW_PAGE, JOBS_OVERVIEW_PAGE, TEAM_OVERVIEW_PAGE, MEMBER_OVERVIEW_PAGE). The setting holds the page's ID and is edited in the panel's Settings screen. With an overview page set, the module's built-in list route redirects to that page, and the module's "back to the list" links point there. Without one, the built-in list route renders the module's own list view, and if the module has no such route the records only appear through blocks and detail pages.

Publishing module files ​

Each module offers vendor:publish tags. <key>.config publishes its config to config/<key>.php, <key>.components publishes its block definitions to config/components/ and, for most modules, views and Livewire components into the project. Several modules add <key>.blueprints for their blueprint classes into app/Blueprints. Published copies stop following the package: a module view you published has to be compared by hand after an update, because evolve:view-overrides only covers core views. The tags per module and the target paths are listed in Publishing and Overriding Package Files.

Demo content ​

php artisan evolve:demo seeds demo records for every enabled module into an install, plus a Kitchen Sink page with one block per blueprint. In the package repository, vendor/bin/testbench workbench:build does the same for the standalone workbench.

Verifying ​

  • php artisan route:list --path=evolve/<key> lists the module's panel routes, each carrying the role: middleware that applies. Nothing is listed for a module that is off.
  • The panel sidebar shows the module to a user with access.
  • Over MCP, the list-modules tool returns the enabled modules.
  • php artisan evolve:env:show live shows the EVOLVE_MODULE_* lines of a remote environment, evolve:env:diff compares them across environments.