Installation
Overview
WebBlocks CMS supports a package-consumer install flow for fresh Laravel applications, a browser-based install wizard for fresh maintenance-repo installs, and a manual Laravel CLI install path.
For a fresh install, start by getting the WebBlocks CMS source code onto your machine. Run Composer, create .env, use Artisan, and open the browser install wizard only after the source code exists locally.
An install is considered complete when the application has a working CMS baseline:
- an app key exists
- the database is reachable
- required tables exist
- core seed data exists
- the first active
super_adminexists - an install completion marker is stored in
system_settings
Get the Source Code
Before you run any install commands, make sure the WebBlocks CMS repository is present locally.
Clone into a new directory:
git clone https://github.com/fklavyenet/webblocks-cms.git
cd webblocks-cms
git remote set-url --push origin DISABLED
Clone into an already-created empty directory:
git clone https://github.com/fklavyenet/webblocks-cms.git .
git remote set-url --push origin DISABLED
After the source code is present locally, continue with one of the fresh install paths below.
WebBlocks CMS installations are update consumers only. They may fetch, pull, or download CMS updates, but they must not push commits or tags back to the canonical CMS upstream. For existing local installation clones, run git remote set-url --push origin DISABLED once in the installation working copy.
Package Consumer Install
Use this flow when WebBlocks CMS is installed into a fresh Laravel application through Composer.
composer require fklavyenet/webblocks-cms
php artisan webblocks:install --name="Admin User" --email="admin@example.com" --password="secret-password"
Supported options:
--name=first super admin display name--email=first super admin email address--password=first super admin password--site-name=default site name--site-handle=default site handle--repair-partialrename empty partial CMS tables before fresh-install migrations--forceoverwrite package-owned CMS assets or published config files when needed
What webblocks:install does:
- publishes
config/webblocks-cms.phpwhen the host app does not already have it - removes the untouched fresh Laravel welcome route from
routes/web.phpwhen it is safe, with a timestamped backup first, so CMS public routes can serve/ - patches
app/Models/User.phpwithWebBlocks\Cms\Auth\Concerns\HasWebBlocksCmsAccess - creates a timestamped backup before modifying
User.php - skips patching when the trait is already present
- fails clearly if
User.phpis not a recognizableApp\Models\User extends Authenticatableclass - runs the package fresh-install migration path for clean consumer installs
- detects partial CMS schemas before running fresh-install migrations and reports existing CMS tables, row counts, related migration rows, and known foreign key conflicts
- repairs empty partial CMS schemas only when
--repair-partialis provided, by renaming empty CMS tables with a timestamped_before_cms_install_...suffix before continuing - refuses automatic repair when any partial CMS table contains rows
- skips rerunning that fresh schema when CMS tables already exist
- creates Laravel support tables without running host application migrations, currently covering CMS password reset tokens plus
sessions,cache, andcache_lockswhen those database-backed drivers are configured - does not run the host application's normal Laravel migration set as part of package install, so it avoids conflicts with the already-created CMS-compatible
userstable - prepares the
backupsfilesystem disk root used by Backup / Restore - installs package-owned CMS assets into
public/cms - creates
public/storagewhen it is missing and the environment allows it - seeds locales, sites, slot types, page layouts, icons, and core block types idempotently
- records the installed version and install completion marker in
system_settings - creates the first active
super_adminonly when one does not already exist
Package auth is Laravel-native and does not require Breeze, Jetstream, Laravel UI, or Fortify. After install, sign in at /webadmin/login when CMS package auth routes are active. CMS-owned auth views and admin guest redirects use package route names such as webblocks.auth.login and webblocks.auth.logout, so a host product can keep its own global login route, for example /quiztem/login, without stealing CMS form actions or /webadmin redirects.
For the current v1.32.x package-consumer boundary, the host application's App\Models\User remains the auth model and install-time patch target.
Partial Install Recovery
If webblocks:install stops after a failed or interrupted prior run, rerun it without repair first and read the partial-install diagnostic. Empty CMS tables can be moved aside explicitly:
php artisan webblocks:install --repair-partial --name="Admin User" --email="admin@example.com" --password="secret-password"
The repair mode only renames empty CMS-owned candidate tables. It does not drop tables, does not alter non-empty tables automatically, and does not assume CMS owns the host application.
Browser Install Wizard
Use the browser wizard for a fresh install.
After the source code is present locally, start with:
composer install
cp .env.example .env
php artisan serve
Then open http://127.0.0.1:8000/install.
The wizard covers:
- environment readiness checks
- database configuration and connection validation
- core CMS installation
- first
super_admincreation - install locking after completion
Notes:
- the installer is for fresh installs
- if setup is incomplete, the wizard can be reopened and resumed safely
- after completion, install routes are locked and normal auth/admin flow takes over
- the installer writes the selected database configuration into
.env
Manual CLI Installation
Use the CLI flow when you prefer a standard Laravel setup path for a fresh install.
composer install
cp .env.example .env
php artisan key:generate
php artisan migrate
php artisan db:seed
php artisan storage:link
php artisan serve
Notes:
php artisan db:seedinstalls the core CMS catalogs and records the current app version as the installed version for a fresh installphp artisan storage:linkis required if public file serving should usestorage/app/public- runtime directories under
storage/framework,storage/logs, andbootstrap/cacheare created automatically on first run - Backup / Restore stores archives on the
backupsfilesystem disk, defaulting tostorage/app/backups. The PHP runtime user should own that directory or share a deployment group with read/write access; avoid broad777modes.
Native Local Install
For a fresh Laravel project running with locally installed PHP and Composer:
composer require fklavyenet/webblocks-cms
php artisan webblocks:install --name="Admin User" --email="admin@example.com" --password="secret-password"
Then open:
- public site:
/ - admin login:
/webadmin/login - admin:
/webadmin
After the source code is present locally:
composer install
cp .env.example .env
php artisan key:generate
Notes:
- trusted local development should use
.testdomains and HTTPS, withhttps://webblocks-cms.testas the canonical CMS development URL php artisan serveremains useful for quick CLI-only checks, but trusted browser workflows should use the native Nginx/PHP-FPM setup documented indocs/native-local-development.md- local contact form email notifications should use a local SMTP catcher or trusted SMTP test account; the usual local SMTP values depend on the installed tool
- Contact Form notification recipients resolve in this order: block-level
recipient_email, current site's default contact recipient,CONTACT_RECIPIENT_EMAIL, thenMAIL_FROM_ADDRESSas the last safe fallback - contact submissions are stored independently from notification delivery, so a public
Message sentresponse confirms storage success even if admin later shows notificationFailed,Skipped, orNot configured MAIL_MAILER=log,MAIL_MAILER=array, andMAIL_MAILER=nullare not real outbound delivery and are shown as not configured for Contact Message notification- Contact Form blocks render a CMS-owned hidden
.wb-form-checkwrapper withinert,aria-hidden="true", a renderer-generatedform_check_{token}field,tabindex="-1", andautocomplete="off"; when that generated check field is filled, the server returns the same generic success redirect and does not store a Contact Message or attempt notification - submissions that pass the generated check field can still be classified as
spamby conservative stored signals such as commercial outreach language, link density, repeated same-IP submissions, or a free-mail sales pitch with a generic subject; this status is durable admin classification and is separate from email notification state - when notification delivery fails, admins can inspect the saved message under
Admin -> Contact Messagesto see the compact failure state in the list and the stored failure detail on the message detail screen
Then open:
- public site:
https://webblocks-cms.test - admin:
https://webblocks-cms.test/webadmin - installer on a fresh install:
https://webblocks-cms.test/install
Complete the fresh install in the browser wizard after those setup steps are done.
Accessing the Install Wizard
- fresh installs automatically redirect to
/install - you can also open the wizard manually at
/install - you can open
/install/coreto jump directly to the core install step when earlier requirements are already satisfied - the wizard may advance steps automatically as requirements are completed
- opening
/and/installin multiple browser tabs can show different wizard steps; this is expected because the installer tracks progress and routes accordingly
First Super Admin Creation
The first super_admin is required for a completed install.
- in the browser wizard, create the first admin during the final setup step
- in the package-consumer CLI flow, provide
--name,--email, and--passwordtowebblocks:install - in a manual install, ensure at least one active
super_adminaccount exists before considering the CMS fully installed
super_admin is the install-level role that can access Users, sites, locales, settings, updates, backups, export/import, and all site content.
Common Setup Notes
- the installer is locked after completion
/webadminis the canonical CMS admin entry point- package-consumer installs may sign in through
/webadmin/login; co-installed apps may keep host-owned/login /webadmin/dashboardredirects to/webadmin- CMS assets stay under
/cms, for example/cms/css,/cms/js, and/cms/brand - package-owned
/webadmin/loginuses package Blade views, the WebBlocks UI guest auth shell, pinned WebBlocks UI assets,/cms/css/guest.css, and CMS product brand assets from/cms/brand, including normal, dark-surface, on-accent/inverse, and high-contrast favicon/browser-tab variants /cmsis reserved for CMS-owned static public assets and must not be used as a CMS admin route prefix, alias, or redirect/adminis not CMS-owned and must not be restored as a CMS admin route- new pages start in
draft - if install-level features such as revisions, backups, or updates report missing tables, run
php artisan migrate
The /webadmin and /cms split avoids the Nginx try_files collision where /cms/ can be resolved as the physical public/cms/ asset directory before Laravel handles a route. Do not solve admin access by adding a public/cms/index.php handoff; that front-controller bridge must stay absent from root and package public assets.
Email And Contact Form Readiness
Configure Laravel mail delivery before publishing a public contact page. A typical SMTP .env setup looks like:
MAIL_MAILER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=
MAIL_PASSWORD=
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=no-reply@example.com
MAIL_FROM_NAME="Site Name"
CONTACT_RECIPIENT_EMAIL=contact@example.com
MAIL_* controls Laravel mail delivery for Contact Form notification attempts. MAIL_FROM_ADDRESS is the safe fallback sender/from address and is also the last safe Contact Form recipient fallback when no more specific recipient is configured. CONTACT_RECIPIENT_EMAIL is optional and acts as an environment-level fallback recipient. Prefer configuring the site-level Contact recipient in Site -> Edit -> Contact when available, so contact routing lives with the site instead of only in .env.
After changing production or package-install .env mail settings, clear cached configuration if the install uses config caching:
php artisan optimize:clear
Contact Form notifications resolve recipients in this order:
- Contact Form block
recipient_email - Site default contact recipient from
Site -> Edit -> Contact .envCONTACT_RECIPIENT_EMAIL- safe
MAIL_FROM_ADDRESSfallback
Accepted real Contact Form submissions are stored before email notification is attempted. Notification failure does not mean the public form submission failed. Admins should check /webadmin/contact-messages for stored messages, notification status, and safe failure details. Public visitors should only see normal success or validation feedback, not mail diagnostics.
Sent means the CMS handed the notification to the configured mail transport without an exception; it does not guarantee inbox delivery. Skipped or Not configured means no real notification send was attempted.
Use the native contact_form block for contact pages. Do not replace it with Trusted HTML, raw <form> markup, or mailto: fallbacks. The CMS renderer generates the hidden anti-spam check field automatically; do not create it manually. The old website honeypot field is no longer the public contract.
Practical Contact Form smoke test:
- Publish or preview a page containing the native
contact_formblock. - Submit a test message with name, email, subject, and message.
- Open
/webadmin/contact-messages. - Confirm the message was stored.
- Review notification status.
- If email did not arrive, inspect the safe failure details and run mail diagnostics.
Diagnostic commands:
php artisan contact:mail-diagnose
php artisan contact:mail-diagnose --block=ID
php artisan contact:mail-diagnose --send-test=you@example.com
The diagnostic command must not print passwords, tokens, or mail secrets. Use --block=ID to inspect the recipient fallback chain for one Contact Form block. Use --send-test= only for a controlled SMTP send check to an intentional test address.
Post-Install Next Steps
- Sign in to
/webadmin. - Review your site and locale configuration.
- Configure site identity and domains.
- Configure Laravel mail settings or approved system mail settings.
- Configure a Contact Form recipient, preferably on
Site -> Edit -> Contact. - Run
php artisan contact:mail-diagnose. - Submit a test native Contact Form and confirm it stores a Contact Message.
- Review email notification status for that test message.
- Create your first page.
- Add media, navigation, and blocks.
- Publish content through the editorial workflow.