Skip to content

Maintenance mode ​

A coming soon or maintenance page for visitors while you work on the site.

kitloom/maintenance · admins: kitloom/maintenance-filament, kitloom/maintenance-nova

Video lessons ​

Recorded in the Filament admin; the Nova admin works the same way.

Maintenance mode

Shows visitors a coming soon or down for maintenance page while you work on the site, the way SeedProd or "Coming Soon Page & Maintenance Mode" does on a WordPress site. The admin panel stays open; you and the roles you choose see the site as it is, and so does anyone you give the access link to — a client, a reviewer — account or not. The settings are in the admin under Maintenance → Settings (kitloom/maintenance-filament or kitloom/maintenance-nova).

Nothing is installed on the server for it and no page is created: the mode is a setting, the page is drawn by the theme.

Switching it on ​

  1. Open Maintenance → Settings.
  2. Visitors see: choose a mode (see below).
  3. Roles that still see the site: administrators by default. Tick the roles whose signed-in users should see the site as it is — editors filling it, for example. Everyone else gets the holding page, signed in or not.
  4. Keep the REST API open while the site is closed: off by default. Turn it on when a headless front end (a separate app) reads the site's content over /wp-json/wp/v2/ — see "The REST API" below.
  5. Headline, Text, Image: what the page says and shows. Empty fields take the mode's own words, in the site's language. The text is HTML, and a shortcode works in it — a form from the Forms module takes "tell me when it opens" addresses.
  6. Save Changes. From now on every address of the site — the front page, posts, archives, a missing page — answers with the holding page.

Open the site in a private window to see what a visitor sees.

The two modes ​

ModeStatusFor
Coming soon200A site that is not open yet. Search engines may index the page, so the domain starts to be known.
Maintenance503 with Retry-AfterA site that is open but briefly closed. Search engines keep what they have and come back later; nothing is indexed.

The holding page is never kept by the browser or by the site's page cache (see below), so switching the mode off shows the site at once.

Status → Access link is an address of the form https://example.com/?access=…. Whoever opens it gets a cookie and is sent on to the page they asked for; from then on that browser sees the site for seven days (kitloom-maintenance.link.days). The link is made the first time the mode is switched on.

New access link makes another one: the old link stops working, and so do the browsers it opened. Make a new one when a link got into the wrong hands or when the review is over.

Someone with an account does not need the link: they sign in, and their role decides. The holding page links to the login form when the site has an account page (Settings → Reading → Account page) and Link to the login form is on.

What stays open ​

  • The admin panel, for everyone who may use it — whatever the mode.
  • The site's own forms: signing in, resetting a password, the account page's forms.
  • The routes of modules under /wp-json/ — a form on the holding page still sends its message — and the index /wp-json/ itself, which lists routes, not content. A headless front end asking for a page of the site as JSON is told the mode instead ({"code": "coming_soon", "message": "…", "data": {"status": 200}} or "maintenance" with 503).

The REST API ​

WordPress's content routes, /wp-json/wp/v2/… (kitloom/api), would list every published post of a closed site to anyone who asks. While the mode is on, whoever sees the holding page gets an error there instead of the content — the holding page's headline as a WordPress error, with a 503 in both modes, so a client asking for posts never takes it for a list:

json
{"code": "coming_soon", "message": "Coming soon", "data": {"status": 503}}

In maintenance mode the code is maintenance and the answer carries Retry-After. Who still reads them:

  • a browser with the access link's cookie — a reviewer's preview of a front end on the same domain;
  • a user of one of the Roles that still see the site, sending their application password; any other user's password is held like a visitor;
  • everyone, when Keep the REST API open while the site is closed is on — for a headless front end that builds its pages from wp/v2 and shows its own holding page.

Only reads are held (GET, HEAD): a write needs an application password and the right to write anyway. The routes of other modules (/wp-json/contact-form-7/v1/…, the shop's, the bookings') are theirs and stay open.

The theme ​

A theme draws the holding page with its coming-soon template — templates/coming-soon.blade.php in a Blade theme, Templates/coming-soon.vue in a Vue theme — and gets the comingSoon part: the mode, the headline, the text with its shortcodes run, the image, the login link. The themes that ship with kitloom have one. A theme without it gets a plain page from the module: the headline, the text, the image, one line with the site's name and the login link. Publish and change it with:

bash
php artisan vendor:publish --tag=kitloom-maintenance-views

Laravel's own maintenance mode ​

php artisan down is something else: it closes the whole application — admin panel included — without touching the database, for the minutes a deploy takes, and php artisan up opens it again. This module is the owner's switch for the site's visitors, with the admin at work behind it.

The two meet in one place: down can show this module's page instead of Laravel's. The view is rendered once, when the command runs and the database is still there, so it says what Maintenance → Settings says:

bash
php artisan down --render="kitloom-maintenance::down" --retry=60

The page cache ​

While the mode is on no page is served from kitloom/site's page cache: a visitor would get the page kept before the switch, and the holding page is a different answer for every visitor (the roles, the cookie). Saving the settings moves the cache on, as saving any option does, so the site comes back fresh when the mode is switched off.

Who may switch it ​

Maintenance → Settings is behind its own permission, manage_maintenance_mode, given to administrators when the module is installed. The roles screen (kitloom/permissions) gives it to other roles. An editor who may change the reading settings cannot close the site.

For AI agents ​

With kitloom/ai installed an agent gets maintenance_settings_get and maintenance_settings_update — the same settings, the access link read and renewed (new_access_link: true) but never chosen — behind the same permission. kitloom-maintenance.ai.register turns them off.

For developers ​

  • Options, one row each: maintenance_mode (off, coming-soon, maintenance), maintenance_headline, maintenance_text, maintenance_image (an attachment id), maintenance_roles (a JSON list of role keys), maintenance_login_link, maintenance_rest_open, maintenance_access_token (protected: the module writes it).
  • The hold happens on kitloom/site's PageResponding event — WordPress's template_redirect — after the canonical redirect, with the main query's result; a page drawn without a request (Site::render(), the console, an agent) is never held. TemplateCandidates puts coming-soon first for a held request.
  • /wp-json/wp/v2/ reads are held by a global middleware (Kitloom\Maintenance\Http\HoldRestReads): the REST root has no web middleware and the namespace's routes are kitloom/api's. A request without an application password is held at once; one with a password is answered by the API and then held if its user's role does not pass. The access link's cookie is read encrypted there, as the browser keeps it.
  • Kitloom\Maintenance\MaintenanceMode (per request) answers active(), status() and passes($request); Kitloom\Maintenance\AccessLink makes, checks and answers the link.
  • Config: kitloom-maintenance.link (query, cookie, days), retry_after, and the filament, nova, ai switches.

kitloom — modules and themes for Laravel.
Pricing · Services · License · Refunds · Privacy · Community · [email protected]