@consilioweb/payload-maintenance
v0.4.0
Published
Payload CMS plugin — customizable maintenance mode page with i18n support
Maintainers
Readme
About
@consilioweb/payload-maintenance — A complete, production-ready maintenance mode plugin for Payload CMS 3 + Next.js. Includes 12 professional templates (Aurora, Neon, Mesh, Particles...), 12 one-click presets, i18n in 10 languages, scheduled maintenance, GDPR-compliant newsletter with unsubscribe, audit history, webhooks with retry (Slack/Discord), rate limiting, HTTP 503 SEO, and a full admin dashboard. Self-contained — no manual route needed.
Table of Contents
- Features
- Installation
- Quick Start
- Templates
- Presets
- Plugin Options
- Middleware Options
- API Endpoints
- Collections
- Bypass Maintenance
- Package Exports
- Requirements
- License
Features
12 Professional Templates
| Template | Description |
|----------|-------------|
| minimal | Clean icon + message layout |
| countdown | SVG circular ring countdown |
| coming-soon | Flip card countdown with separators |
| glassmorphism | Frosted glass card with floating orbs |
| gradient | Multi-color animated gradient background |
| split-screen | Content left, image right (responsive) |
| video-background | MP4 video with overlay |
| aurora | NEW Northern lights with animated gradient layers, floating particles, SVG waves |
| neon | NEW Cyberpunk with pulsing neon glow, grid background, scanline, corner brackets |
| mesh | NEW Apple-like animated blobs with mix-blend-mode and noise texture |
| particles | NEW Canvas-based interactive particle system with mouse interaction |
| custom | Full custom HTML with {{variables}} |
12 One-Click Presets
Pre-configured templates with colors, fonts, and messages — apply in one click from admin:
| Preset | Template | Style |
|--------|----------|-------|
| corporate-blue | countdown | Professional dark blue (Inter) |
| startup-launch | gradient | Purple/pink dynamic (Space Grotesk) |
| minimal-elegant | minimal | Clean dark (DM Sans) |
| glass-premium | glassmorphism | Luxurious purple (Outfit) |
| coming-soon-creative | coming-soon | Teal creative (Sora) |
| light-clean | minimal | Light mode (Plus Jakarta Sans) |
| warm-gradient | gradient | Warm orange tones (Poppins) |
| tech-dark | countdown | Cyan tech (JetBrains Mono) |
| aurora-borealis | aurora | NEW Teal/violet northern lights (Space Grotesk) |
| cyberpunk-neon | neon | NEW Magenta/cyan cyberpunk (Orbitron) |
| mesh-modern | mesh | NEW Indigo/rose modern blobs (Geist) |
| particles-cosmic | particles | NEW Deep space constellation (Inter) |
Multi-Language (i18n)
- 10 languages built-in: FR, EN, DE, ES, IT, PT, NL, JA, AR, ZH
- Auto-detection of browser language
- Language switcher on the maintenance page
- Per-language messages configurable from admin
Scheduled Maintenance
- Set start and end dates
- Auto-enable and auto-disable toggles
- Schedule check endpoint for cron integration
Newsletter Subscribers (GDPR-compliant)
- Email signup form on the maintenance page
- GDPR consent required (
consent: truein POST body) consentAt,consentSourcestored per subscriber- Unsubscribe endpoint with unique token per subscriber
- Stored in a dedicated Payload collection
- Duplicate prevention
- CSV export endpoint for admin users
- Tracks language, IP, user-agent
Security & Rate Limiting
- Rate limiting on all public endpoints (status: 60/min, newsletter: 5/min, track: 30/min per IP)
- Auth check on all admin endpoints (toggle, stats, export, analytics, schedule-check, presets apply)
- Email validation with regex on newsletter signup
- Webhook retry with exponential backoff (3 attempts: 1s, 2s, 4s)
Audit History
- Logs every activation/deactivation
- Records who triggered it and when
- Calculates maintenance duration
- Viewable in admin dashboard
Webhooks & Notifications
- Slack — formatted message with emoji
- Discord — markdown formatted
- Custom webhook — JSON payload
- Email notification — via Payload email adapter
- Fires on every toggle
SEO
- HTTP 503 status code (configurable)
- Retry-After header (dynamic from estimated end date)
robots: noindexon maintenance page
Design Customization
- Google Fonts — dynamic loading by name
- Lottie animations — via URL
- Dark / Light / Auto mode (system preference detection)
- Custom CSS and Custom HTML support
- Background image, video, split image uploads
- Logo and favicon uploads
- Social links (8 platforms)
- Contact email display
Admin Dashboard
- Quick toggle on/off from dashboard
- Live preview iframe
- Subscriber count with CSV export link
- Recent history timeline
- Visual preset gallery with one-click apply
- Link to full global configuration
Installation
pnpm add @consilioweb/payload-maintenanceOr with npm/yarn:
npm install @consilioweb/payload-maintenance
yarn add @consilioweb/payload-maintenancePeer Dependencies
| Package | Version | Required |
|---------|---------|----------|
| payload | ^3.0.0 | Yes |
| @payloadcms/next | ^3.0.0 | Optional (admin views) |
| @payloadcms/ui | ^3.0.0 | Optional (admin UI) |
| @payloadcms/translations | ^3.0.0 | Optional (i18n) |
| next | ^14.0.0 \|\| ^15.0.0 | Optional |
| react | ^18.0.0 \|\| ^19.0.0 | Optional |
Quick Start
1. Add the plugin
// payload.config.ts
import { maintenancePlugin } from '@consilioweb/payload-maintenance'
export default buildConfig({
plugins: [
maintenancePlugin({
languages: [
{ label: 'Francais', value: 'fr' },
{ label: 'English', value: 'en' },
],
}),
],
})2. Add the middleware
// src/middleware.ts
import { NextResponse, type NextRequest } from 'next/server'
import { createMaintenanceMiddleware } from '@consilioweb/payload-maintenance/middleware'
const maintenanceMiddleware = createMaintenanceMiddleware()
export async function middleware(request: NextRequest) {
const maintenanceResponse = await maintenanceMiddleware(request)
if (maintenanceResponse) return maintenanceResponse
return NextResponse.next()
}
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico)$).*)'],
}3. Regenerate importmap
pnpm generate:importmapThat's it! The plugin automatically adds:
- A Maintenance global in Settings
- 4 collections (subscribers, history, analytics, webhook-logs)
- 13 API endpoints (including standalone HTML page — no route needed!)
- An admin dashboard view at
/admin/maintenance - A toggle widget on the admin dashboard
Note: The maintenance page is self-contained — the plugin serves a standalone HTML page via
/api/maintenance/page. No need to create a/maintenanceroute in your Next.js app.
Plugin Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| globalSlug | string | 'maintenance' | Slug du global de configuration |
| endpointBasePath | string | '/maintenance' | Préfixe des endpoints API |
| languages | {label, value}[] | [{fr}, {en}] | Langues disponibles pour la page de maintenance |
| excludedPaths | string[] | ['/admin', '/api'] | Chemins toujours accessibles (jamais bloqués) |
| allowedIPs | string[] | [] | Adresses IP qui contournent le mode maintenance |
| bypassSecret | string | undefined | Paramètre query secret pour contourner la maintenance (ex: ?bypass=secret123) |
| maintenancePageComponent | string | undefined | Chemin vers un composant custom pour la page de maintenance (remplace le défaut) |
| addDashboardView | boolean | true | Ajouter la vue admin à /admin/maintenance |
| bypassCookieName | string | 'maintenance-bypass' | Nom du cookie de contournement |
| mediaCollectionSlug | string | 'media' | Slug de la collection pour les uploads |
| enableSubscribers | boolean | true | Activer la collection d'abonnés newsletter |
| subscribersSlug | string | 'maintenance-subscribers' | Slug de la collection abonnés |
| enableHistory | boolean | true | Activer la collection d'historique/audit |
| historySlug | string | 'maintenance-history' | Slug de la collection historique |
| enableScheduling | boolean | true | Activer la maintenance planifiée (activation/désactivation auto) |
| authBypass | boolean | true | Les utilisateurs Payload connectés contournent la maintenance |
| usersCollectionSlug | string | 'users' | Slug de la collection utilisateurs pour le contournement auth |
| enableAnalytics | boolean | true | Activer le suivi analytique des pages vues pendant la maintenance |
| analyticsSlug | string | 'maintenance-analytics' | Slug de la collection analytique |
| webhookLogsSlug | string | 'maintenance-webhook-logs' | Slug de la collection de logs webhook |
| showDashboardToggle | boolean | true | Afficher le toggle maintenance sur le dashboard admin principal |
Middleware Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| excludedPaths | string[] | ['/admin', '/api'] | Never-blocked paths |
| cacheDuration | number | 10 | Status cache (seconds) |
| return503 | boolean | true | HTTP 503 for SEO |
| authBypass | boolean | true | Logged-in users bypass |
| authCookieName | string | 'payload-token' | Payload auth cookie |
| bypassCookieName | string | 'maintenance-bypass' | Bypass cookie |
| apiUrl | string | Same origin | Custom API URL |
API Endpoints
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| GET | /api/maintenance/status | Public | Full maintenance status |
| POST | /api/maintenance/toggle | Admin | Toggle on/off |
| POST | /api/maintenance/newsletter | Public | Newsletter signup |
| GET | /api/maintenance/stats | Admin | Subscribers count + history |
| GET | /api/maintenance/subscribers/export | Admin | CSV export |
| GET | /api/maintenance/presets | Public | List available presets |
| POST | /api/maintenance/presets/apply | Admin | Apply a preset |
| GET | /api/maintenance/schedule-check | Admin | Check scheduled dates |
| GET | /api/maintenance/page | Public | Standalone HTML maintenance page |
| POST | /api/maintenance/track | Public | Analytics page view tracking |
| GET | /api/maintenance/analytics | Admin | Analytics data |
| GET | /api/maintenance/unsubscribe | Public | Unsubscribe by token |
Collections
The plugin automatically creates two collections:
maintenance-subscribers
| Field | Type | Description |
|-------|------|-------------|
| email | email (unique) | Subscriber email |
| language | text | Browser language |
| subscribedAt | date | Registration date |
| ip | text | IP address |
| userAgent | text | Browser user agent |
| consentAt | date | GDPR consent timestamp |
| consentSource | text | Consent origin (maintenance-page) |
| unsubscribeToken | text (unique) | Token for unsubscribe link |
maintenance-history
| Field | Type | Description |
|-------|------|-------------|
| action | select | activated / deactivated / scheduled-start / scheduled-end |
| triggeredBy | text | User email or "system" |
| timestamp | date | When it happened |
| duration | text | Maintenance duration (on deactivation) |
| details | json | Template, message count, etc. |
Bypass Maintenance
Multiple ways to bypass the maintenance page:
| Method | How |
|--------|-----|
| Bypass cookie | Visit ?bypass=YOUR_SECRET — sets a 24h cookie |
| IP whitelist | Configure allowed IPs in admin (Access tab) |
| Auth bypass | Logged-in Payload admin users automatically see the real site |
| Route exclusion | Exclude specific routes (e.g. /pricing, /legal/*) in admin |
| Path exclusion | /admin and /api are always accessible |
Package Exports
// Server — plugin, types, globals, endpoints, collections, presets
import {
maintenancePlugin,
createMaintenanceGlobal,
createSubscribersCollection,
createHistoryCollection,
presets,
getPreset,
presetToPayloadData,
} from '@consilioweb/payload-maintenance'
import type {
MaintenancePluginConfig,
MaintenanceMessage,
MaintenanceStatus,
MaintenanceTemplate,
SocialLink,
WebhookConfig,
MaintenancePreset,
} from '@consilioweb/payload-maintenance'
// Client — React components
import {
MaintenancePage,
MaintenanceToggle,
MaintenanceViewClient,
} from '@consilioweb/payload-maintenance/client'
// Views — server components for admin
import { MaintenanceView } from '@consilioweb/payload-maintenance/views'
// Middleware — Next.js middleware helper
import { createMaintenanceMiddleware } from '@consilioweb/payload-maintenance/middleware'
import type { MaintenanceMiddlewareConfig } from '@consilioweb/payload-maintenance/middleware'Requirements
- Node.js >= 18
- Payload CMS 3.x
- Next.js 14.x or 15.x
- React 18.x or 19.x
- Database: Any Payload-supported adapter (SQLite, PostgreSQL, MongoDB)
Uninstall
- Remove the plugin from
payload.config.ts - Remove the middleware from
src/middleware.ts - Uninstall:
pnpm remove @consilioweb/payload-maintenance - Regenerate importmap:
pnpm generate:importmap
Data cleanup (optional)
The plugin collections remain in your database. To remove them:
SQLite:
DROP TABLE IF EXISTS "maintenance-subscribers";
DROP TABLE IF EXISTS "maintenance-history";License
Author
Made with passion by ConsilioWEB
