How to add a custom maintenance mode screen in WordPress

The goal is to make a simple to use maintenance PhP code snippet.

When updating or redesigning your website, it’s often a good idea to activate maintenance mode to prevent visitors (and search engines) from seeing a broken or incomplete site. In this tutorial, I’ll show you how I created a custom maintenance screen in WordPress — no plugin needed. This solution is great if you want full control and lightweight functionality without installing extra plugins.

I have made two examples. Both are activated through the backend – WordPress Settings and a new Maintenance Mode submenu will show up. When maintenance is on the site is not visible for external users or search engines. So that one can work in with modifying or finishing the site without anyone noticing the work being done.

Version 1: A simple screen with maintenance information.

As the none logged in user enters the site they will see a Maintenance Mode screen.

function display_maintenance_mode() {
    if (!current_user_can('manage_options')) {
        wp_die('
        <!DOCTYPE html>
        <html>
        <head>
            <title>Site Maintenance</title>
            <style>
                body {
                    font-family: Arial, sans-serif;
                    text-align: center;
                    padding: 50px;
                    background: #f5f5f5;
                }
                .container {
                    max-width: 400px;
                    margin: 0 auto;
                    background: white;
                    padding: 30px;
                    border-radius: 5px;
                    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
                }
                h1 { color: #333; }
                p { color: #666; line-height: 1.5; }
            </style>
        </head>
        <body>
            <div class="container">
                <h1>🔧 Maintenance Mode</h1>
                <p>We\'re currently working on site security improvements.</p>
                <p>We\'ll be back online Monday morning.</p>
                <p>Thanks for your patience!</p>
            </div>
        </body>
        </html>
        ', 'Maintenance Mode', array('response' => 503));
    }
}
add_action('wp', 'display_maintenance_mode');

Version 2: Maintenance Mode with Login Redirect

  • Enables maintenance mode via checkbox in Settings → Maintenance Mode.
  • Always redirects visitors (not logged in) to the login screen.
  • Blocks search engines via HTTP headers.

NB! Do a few hard refreshes if it does not at first show up. As the cache/memory needs to be cleared.

Enable Maintenance Mode - redirect to login screen using a code snippet
Enable Maintenance Mode – redirect to login screen using a code snippet
// 1. Add "Maintenance Mode" page under Settings
add_action('admin_menu', function () {
    add_options_page(
        'Maintenance Mode',
        'Maintenance Mode',
        'manage_options',
        'custom-maintenance-mode',
        'custom_maintenance_mode_settings_page'
    );
});

// 2. Register setting
add_action('admin_init', function () {
    register_setting('custom_maintenance_mode_group', 'custom_maintenance_mode_enabled');
});

// 3. Display the settings page
function custom_maintenance_mode_settings_page() {
    $enabled = get_option('custom_maintenance_mode_enabled', 0);
    ?>
    <div class="wrap">
        <h1>Maintenance Mode</h1>
        <form method="post" action="options.php">
            <?php
            settings_fields('custom_maintenance_mode_group');
            do_settings_sections('custom_maintenance_mode_group');
            ?>
            <p>
                <label>
                    <input type="checkbox" name="custom_maintenance_mode_enabled" value="1" <?php checked(1, $enabled); ?> />
                    Enable Maintenance Mode
                </label>
                <p class="description">When enabled, all visitors except logged-in users will be redirected to the login page.</p>
            <?php submit_button(); ?>
        </form>
    </div>
    <?php
}

// 4. Enforce maintenance redirect if enabled
add_action('template_redirect', function () {
    if (!get_option('custom_maintenance_mode_enabled')) return;
    if (is_user_logged_in()) return;

    if (
        is_admin() ||
        defined('REST_REQUEST') ||
        defined('DOING_AJAX') ||
        strpos($_SERVER['REQUEST_URI'], 'wp-login.php') !== false
    ) {
        return;
    }

    // Block search engine indexing
    header('X-Robots-Tag: noindex, nofollow', true);
    header('Retry-After: 3600');

    // Redirect all non-logged-in visitors to the login screen
    wp_redirect(wp_login_url($_SERVER['REQUEST_URI']), 302);
    exit;
});

Version 3: Maintenance Mode with Optional Custom Message or Redirect

  • Adds two radio buttons: “Redirect to login” or “Show custom message”
  • Includes blocking for search engines in both options.
  • Custom message shows with emoji 🌻.
Enable Maintenance Mode redirect to login or show custom message code snippet
Enable Maintenance Mode redirect to login or show custom message code snippet
// 1. Add "Maintenance Mode" page under Settings
add_action('admin_menu', function () {
    add_options_page(
        'Maintenance Mode',
        'Maintenance Mode',
        'manage_options',
        'custom-maintenance-mode',
        'custom_maintenance_mode_settings_page'
    );
});

// 2. Register settings
add_action('admin_init', function () {
    register_setting('custom_maintenance_mode_group', 'custom_maintenance_mode_enabled');
    register_setting('custom_maintenance_mode_group', 'custom_maintenance_mode_behavior');
});

// 3. Display settings page
function custom_maintenance_mode_settings_page() {
    $enabled  = get_option('custom_maintenance_mode_enabled', 0);
    $behavior = get_option('custom_maintenance_mode_behavior', 'message');
    ?>
    <div class="wrap">
        <h1>Maintenance Mode</h1>
        <form method="post" action="options.php">
            <?php
            settings_fields('custom_maintenance_mode_group');
            do_settings_sections('custom_maintenance_mode_group');
            ?>
            <p>
                <label>
                    <input type="checkbox" name="custom_maintenance_mode_enabled" value="1" <?php checked(1, $enabled); ?> />
                    Enable Maintenance Mode
                </label>
            </p>
            <fieldset style="margin-left: 20px; margin-top: 10px;">
                <legend><strong>Select Maintenance Behavior:</strong></legend>
                <label>
                    <input type="radio" name="custom_maintenance_mode_behavior" value="redirect" <?php checked('redirect', $behavior); ?> <?php disabled(!$enabled); ?> />
                    Redirect to login screen
                </label><br />
                <label>
                    <input type="radio" name="custom_maintenance_mode_behavior" value="message" <?php checked('message', $behavior); ?> <?php disabled(!$enabled); ?> />
                    Show a maintenance message
                </label>
            </fieldset>
            <p style="margin-top:10px;">When enabled, logged-out visitors will either be redirected to the login page or shown a custom message.</p>
            <?php submit_button(); ?>
        </form>
    </div>
    <?php
}

// 4. Handle maintenance mode logic
add_action('template_redirect', function () {
    if (!get_option('custom_maintenance_mode_enabled')) return;
    if (is_user_logged_in()) return;

    if (
        is_admin() ||
        defined('REST_REQUEST') ||
        defined('DOING_AJAX') ||
        strpos($_SERVER['REQUEST_URI'], 'wp-login.php') !== false
    ) {
        return;
    }

    $behavior = get_option('custom_maintenance_mode_behavior', 'message');

    // Block search engine indexing in either case
    header('X-Robots-Tag: noindex, nofollow', true);
    header('Retry-After: 3600');

    // Redirect all non-logged-in visitors to the login screen
    if ($behavior === 'redirect') {
        wp_redirect(wp_login_url($_SERVER['REQUEST_URI']), 302);
        exit;
    }

    // Show custom maintenance screen with emoji
    $html = '
    <div style="
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        min-height: 50vh;
        background-color: #f9f9f9;
        color: #333;
        font-family: sans-serif;
        text-align: center;
        padding: 40px;
    ">
        <div style="font-size: 80px; margin-bottom: 20px;">🌻</div>
        <h1 style="font-size: 28px; margin-bottom: 10px;">Maintenance in Progress</h1>
        <p style="font-size: 18px; max-width: 600px;">
            Our site is temporarily offline while we perform some necessary updates.<br />
            We’ll be back shortly — thank you for your patience!
        </p>
    </div>';

    wp_die($html, 'Site Under Maintenance', ['response' => 503]);
});

I used ChaptGPT to create the above code and tutorial. It usually takes 2-3 hours of testing of the code to get it right.

Share the article:

Leave a Reply

Your email address will not be published. Required fields are marked *