Skip to content

Instantly share code, notes, and snippets.

@pitch-gist
Created June 26, 2012 22:21
Show Gist options
  • Save pitch-gist/2999707 to your computer and use it in GitHub Desktop.
Save pitch-gist/2999707 to your computer and use it in GitHub Desktop.
HTML: Simple Maintenance Page
<!doctype html>
<title>Site Maintenance</title>
<style>
body { text-align: center; padding: 150px; }
h1 { font-size: 50px; }
body { font: 20px Helvetica, sans-serif; color: #333; }
article { display: block; text-align: left; width: 650px; margin: 0 auto; }
a { color: #dc8100; text-decoration: none; }
a:hover { color: #333; text-decoration: none; }
</style>
<article>
<h1>We&rsquo;ll be back soon!</h1>
<div>
<p>Sorry for the inconvenience but we&rsquo;re performing some maintenance at the moment. If you need to you can always <a href="mailto:#">contact us</a>, otherwise we&rsquo;ll be back online shortly!</p>
<p>&mdash; The Team</p>
</div>
</article>
@cendana
Copy link

cendana commented Jan 5, 2023

Thanks a lot, very helping for me

@doxt3r
Copy link

doxt3r commented Jan 6, 2023

Hello my friends, let it be multilanguage (translations can be enhanced;):

<?php
// Get the user's preferred languages from the Accept-Language header
$languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);

// Set the default language to English
$lang = 'en';

// Loop through the user's preferred languages and check if we have a translation available
foreach ($languages as $language) {
    $language = strtolower(substr($language, 0, 2));
    if (in_array($language, array('en', 'ar', 'fr', 'es', 'zh', 'pt'))) {
        $lang = $language;
        break;
    }
}

// Set the content-language header to the selected language
header("Content-Language: $lang");

// Translations object
$translations = array(
    'en' => array(
        'title' => 'Site Maintenance',
        'heading' => 'We\'ll be back soon!',
        'text' => 'Sorry for the inconvenience but we\'re performing some maintenance at the moment. If you need to you can always <a href="mailto:#">contact us</a>, otherwise we\'ll be back online shortly!',
        'team' => '&mdash; The Team',
        'day' => 'Days',
        'hour' => 'Hours',
        'minute' => 'Minutes',
        'second' => 'Seconds',
    ),
    'ar' => array(
        'title' => 'صيانة الموقع',
        'heading' => 'سنعود قريبا!',
        'text' => 'نعتذر عن الإزعاج الذي قد يسببه الصيانة الحالية للموقع. في حال كان لديك أي احتياجات يمكنك الاتصال بنا على الفور <a href="mailto:#">بريدنا الإلكتروني</a>، وفي غير ذلك فسنعود على المدى القريب!',
        'team' => '&mdash; فريق العمل',
        'day' => 'أيام',
        'hour' => 'ساعات',
        'minute' => 'دقائق',
        'second' => 'ثواني',
    ),
    'fr' => array(
        'title' => 'Maintenance du site',
        'heading' => 'Nous reviendrons bientôt!',
        'text' => 'Désolé pour le dérangement, mais nous effectuons actuellement des travaux de maintenance. Si vous en avez besoin, vous pouvez toujours <a href="mailto:#">nous contacter</a>, sinon nous serons de retour en ligne prochainement!',
        'team' => '&mdash; L\'équipe',
        'day' => 'Jours',
        'hour' => 'Heures',
        'minute' => 'Minutes',
        'second' => 'Secondes',
    ),
    'es' => array(
        'title' => 'Mantenimiento del sitio',
        'heading' => '¡Volveremos pronto!',
        'text' => 'Disculpe las molestias, pero estamos realizando mantenimiento en este momento. Si lo necesita, siempre puede <a href="mailto:#">contactarnos</a>, ¡de lo contrario volveremos en línea pronto!',
        'team' => '&mdash; El equipo',
        'day' => 'Días',
        'hour' => 'Horas',
        'minute' => 'Minutos',
        'second' => 'Segundos',
    ),
    'zh' => array(
        'title' => '网站维护',
        'heading' => '我们很快就会回来!',
        'text' => '抱歉给您带来不便,但我们目前正在进行维护。如果您需要的话,您随时可以<a href="mailto:#">联系我们</a>,否则我们很快就会恢复在线!',
        'team' => '&mdash; 团队',
        'day' => '天',
        'hour' => '小时',
        'minute' => '分钟',
        'second' => '秒',
    ),
    'pt' => array(
        'title' => 'Manutenção do Site',
        'heading' => 'Voltaremos em breve!',
        'text' => 'Desculpe pelo incômodo, mas estamos realizando manutenção no momento. Se precisar, sempre pode <a href="mailto:#">entrar em contato conosco</a>, senão estaremos de volta online em breve!',
        'team' => '&mdash; O time',
        'day' => 'Dias',
        'hour' => 'Horas',
        'minute' => 'Minutos',
        'second' => 'Segundos',
    ),
);

// Set the protocol
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ?? '';
if (!in_array($protocol, array('HTTP/1.1', 'HTTP/2', 'HTTP/2.0'), true)) {
    $protocol = 'HTTP/1.0';
}

// Set the status code for crawlers like googlebot...
header("$protocol 503 Service Unavailable", true, 503);
header('Content-Type: text/html; charset=utf-8');
header('Retry-After: 30');
?>

<!doctype html>
<html lang="en">
<head>
    <title><?php echo $translations[$lang]['title']; ?></title>
    <meta charset="utf-8">
    <meta name="robots" content="noindex">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        body {
            text-align: center;
            padding: 20px;
            font: 20px Helvetica, sans-serif;
            color: #efe8e8;
            background-color: #2e2929
        }

        @media (min-width: 768px) {
            body {
                padding-top: 150px;
            }
        }

        h1 {
            font-size: 50px;
        }

        article {
            display: block;
            text-align: left;
            max-width: 650px;
            margin: 0 auto;
        }

        a {
            color: #dc8100;
            text-decoration: none;
        }

        a:hover {
            color: #efe8e8;
            text-decoration: none;
        }
    </style>
</head>
<body>
<article>
    <h1><?php echo $translations[$lang]['heading']; ?></h1>
    <div>
        <p><?php echo $translations[$lang]['text']; ?></p>
        <p><?php echo $translations[$lang]['team']; ?></p>
    </div>
    <div style="display: flex; flex-direction: row; justify-content: space-between;">
        <p class="day"></p>
        <p class="hour"></p>
        <p class="minute"></p>
        <p class="second"></p>
    </div>
</article>
<script>

    const countDown = () => {
        const countDay = new Date("01/12/2023"); // please indicate launch date (mm/dd/YYYY) :)
        const now = new Date();
        const counter = countDay - now;
        const second = 1000;
        const minute = second * 60;
        const hour = minute * 60;
        const day = hour * 24;
        const textDay = Math.floor(counter / day);
        const textHour = Math.floor((counter % day) / hour);
        const textMinute = Math.floor((counter % hour) / minute);
        const textSecond = Math.floor((counter % minute) / second)
        document.querySelector(".day").innerText = textDay + ' <?php echo $translations[$lang]['day']; ?>';
        document.querySelector(".hour").innerText = textHour + ' <?php echo $translations[$lang]['hour']; ?>';
        document.querySelector(".minute").innerText = textMinute + ' <?php echo $translations[$lang]['minute']; ?>';
        document.querySelector(".second").innerText = textSecond + ' <?php echo $translations[$lang]['second']; ?>';
    }
    countDown();
    setInterval(countDown, 1000);
</script>
</body>
</html>

@sicenul
Copy link

sicenul commented Feb 17, 2023

Please update with countdown freeze after it reach the countday, currently it continue to minus.
Thank you 😄

edited: well, this is my first try 😃

        const countDown = () => {
            const countDay = new Date('09/21/2023 09:21:00'); //format: MM/DD/YYYY HH:MM:SS
            const now = new Date();
            const counter = countDay - now;
            const second = 1000;
            const minute = second * 60;
            const hour = minute * 60;
            const day = hour * 24;
            const textDay = Math.floor(counter / day);
            const textHour = Math.floor((counter % day) / hour);
            const textMinute = Math.floor((counter % hour) / minute);
            const textSecond = Math.floor((counter % minute) / second);
            if (textSecond < 0) {
              theDay = 0;
              theHour = 0;
              theMinute = 0;
              theSecond = 0;
            } else {
              theDay = textDay;
              theHour = textHour;
              theMinute = textMinute;
              theSecond = textSecond;
            }
            document.querySelector(".day").innerText = theDay + ' Days';
            document.querySelector(".hour").innerText = theHour + ' Hours';
            document.querySelector(".minute").innerText = theMinute + ' Minutes';
            document.querySelector(".second").innerText = theSecond + ' Seconds';
        }
        countDown();
        setInterval(countDown, 1000);

@jigzstar
Copy link

Wow amazing!

@Aljenci
Copy link

Aljenci commented Apr 6, 2023

Getting the default user config for dark or light mode:

<!DOCTYPE html>
<html>
    <head>
        <title>Site Maintenance</title>
        <meta charset="utf-8" />
        <meta name="robots" content="noindex" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <style>
            body {
                text-align: center;
                padding: 20px;
                font: 20px Helvetica, sans-serif;
                color: #333;
                background-color: #ffffff
            }
            @media (min-width: 768px) {
                body {
                    padding-top: 150px;
                }
            }
            h1 {
                font-size: 50px;
            }
            article {
                display: block;
                text-align: left;
                max-width: 650px;
                margin: 0 auto;
            }
            a {
                color: #dc8100;
                text-decoration: none;
            }
            a:hover {
                color: #333;
                text-decoration: none;
            }
            @media (prefers-color-scheme: dark) {
                body {
                    color: #efe8e8;
                    background-color: #2e2929
                }
                a {
                    color: #dc8100;
                }
                a:hover {
                    color: #efe8e8;
                }
            }
        </style>
    </head>
    <body>
        <article>
            <h1>We&rsquo;ll be back soon!</h1>
            <div>
                <p>
                    Sorry for the inconvenience but we&rsquo;re performing some
                    maintenance at the moment. If you need to you can always
                    <a href="mailto:#">contact us</a>, otherwise we&rsquo;ll be
                    back online shortly!
                </p>
                <p>&mdash; The Team</p>
            </div>
        </article>
    </body>
</html>

@obayit
Copy link

obayit commented Apr 6, 2023

@pitch-gist maybe this should be turned into a repo!

@doxt3r
Copy link

doxt3r commented Apr 6, 2023

@obayit good idea ! @pitch-gist can i create the repository, with both full html and php versions ?

@harryfear
Copy link

Go for it! Was thinking the same 😎

@arize99
Copy link

arize99 commented Jun 1, 2023

WTF humans...😂😂😂

@MeLoseAgain
Copy link

Thanks for code, It shortens my work, thank you very much everyone

@freqq68
Copy link

freqq68 commented Oct 18, 2023

@doxt3r Love ur php page <3

@mullernato
Copy link

A small contribution: Site Title, Auto Wait Time, Auto Reload, Contact Link, German Translation, Css Formatting, Reformulated text to be more attractive.

<?php
$time_to_wait = 60; // in seconds
$site_title = 'My Site';
$contact_link = '#';

// Get the user's preferred languages from the Accept-Language header
$languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);

// Set the default language to English
$lang = 'en';

// Loop through the user's preferred languages and check if we have a translation available
foreach ($languages as $language) {
    $language = strtolower(substr($language, 0, 2));
    if (in_array($language, array('en', 'ar', 'fr', 'es', 'zh', 'pt'))) {
        $lang = $language;
        break;
    }
}

// Set the content-language header to the selected language
header("Content-Language: $lang");

// Translations object
$translations = array(
    'en' => array(
        'title' => 'Site Maintenance',
        'heading' => 'We\'ll be back soon!',
        'text' => 'We\'re just sprucing things up a bit! In the meantime, feel free to <a href="' . $contact_link . '">join us on Discord</a> for a chat or to get any assistance you need. We\'ll be up and running in just a moment, and the page will automatically refresh at the end of the countdown below.',
        'team' => '&mdash; The Team',
        'day' => 'Days',
        'hour' => 'Hours',
        'minute' => 'Minutes',
        'second' => 'Seconds',
    ),
    'ar' => array(
        'title' => 'صيانة الموقع',
        'heading' => 'سنعود قريبا!',
        'text' => 'نحن نعمل على تحسين الموقع لك! في هذه الأثناء، لا تتردد في <a href="' . $contact_link . '">الانضمام إلينا على ديسكورد</a> للدردشة أو للحصول على المساعدة التي تحتاجها. سنعود للعمل في لحظات قليلة، وسيتم تحديث الصفحة تلقائياً عند انتهاء العد التنازلي أدناه.',
        'team' => '&mdash; فريق العمل',
        'day' => 'أيام',
        'hour' => 'ساعات',
        'minute' => 'دقائق',
        'second' => 'ثواني',
    ),
    'fr' => array(
        'title' => 'Maintenance du site',
        'heading' => 'Nous reviendrons bientôt!',
        'text' => 'Nous apportons juste quelques améliorations! En attendant, n\'hésitez pas à <a href="' . $contact_link . '">nous rejoindre sur Discord</a> pour discuter ou obtenir l\'aide dont vous avez besoin. Nous serons de retour en un instant, et la page se rafraîchira automatiquement à la fin du compte à rebours ci-dessous.',
        'team' => '&mdash; L\'équipe',
        'day' => 'Jours',
        'hour' => 'Heures',
        'minute' => 'Minutes',
        'second' => 'Secondes',
    ),
    'de' => array(
        'title' => 'Wartung der Website',
        'heading' => 'Wir sind bald zurück!',
        'text' => 'Wir verbessern gerade ein paar Dinge für dich! In der Zwischenzeit kannst du dich gerne <a href="' . $contact_link . '">uns auf Discord anschließen</a>, um zu chatten oder um die Hilfe zu erhalten, die du benötigst. Wir sind in Kürze wieder da, und die Seite wird am Ende des Countdowns unten automatisch aktualisiert.',
        'team' => '&mdash; Das Team',
        'day' => 'Tage',
        'hour' => 'Stunden',
        'minute' => 'Minuten',
        'second' => 'Sekunden',
    ),
    'es' => array(
        'title' => 'Mantenimiento del sitio',
        'heading' => '¡Volveremos pronto!',
        'text' => '¡Estamos mejorando algunas cosas para ti! Mientras tanto, siéntete libre de <a href="' . $contact_link . '">unirte a nosotros en Discord</a> para charlar o para obtener la asistencia que necesitas. Estaremos operativos en un instante, y la página se recargará automáticamente al final de la cuenta regresiva a continuación.',
        'team' => '&mdash; El equipo',
        'day' => 'Días',
        'hour' => 'Horas',
        'minute' => 'Minutos',
        'second' => 'Segundos',
    ),
    'zh' => array(
        'title' => '网站维护',
        'heading' => '我们很快就会回来!',
        'text' => '我们正在为您改善一些事物!同时,欢迎您<a href="' . $contact_link . '">加入我们的Discord</a>进行交流或获取您所需的帮助。我们将很快恢复运行,页面将在下方倒计时结束时自动刷新。',
        'team' => '&mdash; 团队',
        'day' => '天',
        'hour' => '小时',
        'minute' => '分钟',
        'second' => '秒',
    ),
    'pt' => array(
        'title' => 'Manutenção do Site',
        'heading' => 'Voltaremos em breve!',
        'text' => 'Estamos aprimorando algumas coisas para você! Enquanto isso, sinta-se à vontade para <a href="' . $contact_link . '">se juntar a nós no Discord</a> para conversar ou obter a ajuda que precisa. Estaremos de volta num piscar de olhos, e a página será recarregada automaticamente ao final da contagem abaixo.',
        'team' => '&mdash; O time',
        'day' => 'Dias',
        'hour' => 'Horas',
        'minute' => 'Minutos',
        'second' => 'Segundos',
    ),
);

// Set the protocol
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ?? '';
if (!in_array($protocol, array('HTTP/1.1', 'HTTP/2', 'HTTP/2.0'), true)) {
    $protocol = 'HTTP/1.0';
}

// Set the status code for crawlers like googlebot...
header("$protocol 503 Service Unavailable", true, 503);
header('Content-Type: text/html; charset=utf-8');
header('Retry-After: ' . $time_to_wait);
?>

<!doctype html>
<html lang="en">
<head>
    <title><?php echo $site_title . ' - ' . $translations[$lang]['title']; ?></title>
    <meta charset="utf-8">
    <meta name="robots" content="noindex">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        html body {
            text-align: center;
            padding: 20px;
            font: 20px Helvetica, sans-serif;
            color: #333;
            background-color: #ffffff;
        }
        @media (min-width: 768px) {
            html body {
                padding-top: 150px;
            }
        }
        h1 {
            font-size: 50px;
        }
        article {
            display: block;
            text-align: left;
            max-width: 650px;
            margin: 0 auto;
        }
        body a {
            color: #dc8100;
            text-decoration: none;
        }
        body a:hover {
            color: #333;
            text-decoration: none;
        }
        @media (prefers-color-scheme: dark) {
            html body {
                color: #efe8e8;
                background-color: #2e2929;
            }
            body a {
                color: #dc8100;
            }
            body a:hover {
                color: #efe8e8;
            }
        }
    </style>
</head>
<body>
<article>
    <h1><?php echo $translations[$lang]['heading']; ?></h1>
    <div>
        <p><?php echo $translations[$lang]['text']; ?></p>
        <p><?php echo $translations[$lang]['team']; ?></p>
    </div>
    <div style="display: flex; flex-direction: row; justify-content: space-between;">
        <p class="day"></p>
        <p class="hour"></p>
        <p class="minute"></p>
        <p class="second"></p>
    </div>
    <div class="pyro">

    </div>
</article>

<script>
    const stringDate = new Date(Date.now() + <?php echo $time_to_wait ?> * 1000).toLocaleString();
    const countDay = new Date(stringDate); //format: MM/DD/YYYY HH:MM:SS
    const countDown = () => {
            const now = new Date();
            const counter = countDay - now;
            const second = 1000;
            const minute = second * 60;
            const hour = minute * 60;
            const day = hour * 24;
            const textDay = Math.floor(counter / day);
            const textHour = Math.floor((counter % day) / hour);
            const textMinute = Math.floor((counter % hour) / minute);
            const textSecond = Math.floor((counter % minute) / second);

            if (textSecond < 0) {
              theDay = 0;
              theHour = 0;
              theMinute = 0;
              theSecond = 0;

              window.location.reload();
            } else {
              theDay = textDay;
              theHour = textHour;
              theMinute = textMinute;
              theSecond = textSecond;
            }
            document.querySelector(".day").innerText = theDay + ' Days';
            document.querySelector(".hour").innerText = theHour + ' Hours';
            document.querySelector(".minute").innerText = theMinute + ' Minutes';
            document.querySelector(".second").innerText = theSecond + ' Seconds';
        }
        countDown();
        setInterval(countDown, 1000);
</script>
</body>
</html>

@vastris
Copy link

vastris commented Jan 22, 2024

Your HTML simple maintenance page is a practical solution for communicating downtime. It's a smart addition to any website strategy. Additionally, considering app maintenance costs is crucial for sustained performance and user satisfaction.

@Anahit-Ghazaryan
Copy link

Implementing your HTML simple maintenance page serves as a reliable way to notify users during downtime, enhancing overall website strategy. Moreover, factoring in app technical service costs remains vital for ensuring consistent performance and meeting user expectations.

@SilentPSLLC
Copy link

SilentPSLLC commented Mar 7, 2024

Fixed Translation from missing 'de' in translations

<?php
$time_to_wait = 60; // in seconds
$site_title = 'My Site';
$contact_link = '#';

// Get the user's preferred languages from the Accept-Language header
$languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);

// Set the default language to English
$lang = 'en';

// Loop through the user's preferred languages and check if we have a translation available
foreach ($languages as $language) {
    $language = strtolower(substr($language, 0, 2));
    if (in_array($language, array('en', 'ar', 'fr', 'de', 'es', 'zh', 'pt'))) {
        $lang = $language;
        break;
    }
}

// Set the content-language header to the selected language
header("Content-Language: $lang");

// Translations object
$translations = array(
    'en' => array(
        'title' => 'Site Maintenance',
        'heading' => 'We\'ll be back soon!',
        'text' => 'We\'re just sprucing things up a bit! In the meantime, feel free to <a href="' . $contact_link . '">join us on Discord</a> for a chat or to get any assistance you need. We\'ll be up and running in just a moment, and the page will automatically refresh at the end of the countdown below.',
        'team' => '&mdash; The Team',
        'day' => 'Days',
        'hour' => 'Hours',
        'minute' => 'Minutes',
        'second' => 'Seconds',
    ),
    'ar' => array(
        'title' => 'صيانة الموقع',
        'heading' => 'سنعود قريبا!',
        'text' => 'نحن نعمل على تحسين الموقع لك! في هذه الأثناء، لا تتردد في <a href="' . $contact_link . '">الانضمام إلينا على ديسكورد</a> للدردشة أو للحصول على المساعدة التي تحتاجها. سنعود للعمل في لحظات قليلة، وسيتم تحديث الصفحة تلقائياً عند انتهاء العد التنازلي أدناه.',
        'team' => '&mdash; فريق العمل',
        'day' => 'أيام',
        'hour' => 'ساعات',
        'minute' => 'دقائق',
        'second' => 'ثواني',
    ),
    'fr' => array(
        'title' => 'Maintenance du site',
        'heading' => 'Nous reviendrons bientôt!',
        'text' => 'Nous apportons juste quelques améliorations! En attendant, n\'hésitez pas à <a href="' . $contact_link . '">nous rejoindre sur Discord</a> pour discuter ou obtenir l\'aide dont vous avez besoin. Nous serons de retour en un instant, et la page se rafraîchira automatiquement à la fin du compte à rebours ci-dessous.',
        'team' => '&mdash; L\'équipe',
        'day' => 'Jours',
        'hour' => 'Heures',
        'minute' => 'Minutes',
        'second' => 'Secondes',
    ),
    'de' => array(
        'title' => 'Wartung der Website',
        'heading' => 'Wir sind bald zurück!',
        'text' => 'Wir verbessern gerade ein paar Dinge für dich! In der Zwischenzeit kannst du dich gerne <a href="' . $contact_link . '">uns auf Discord anschließen</a>, um zu chatten oder um die Hilfe zu erhalten, die du benötigst. Wir sind in Kürze wieder da, und die Seite wird am Ende des Countdowns unten automatisch aktualisiert.',
        'team' => '&mdash; Das Team',
        'day' => 'Tage',
        'hour' => 'Stunden',
        'minute' => 'Minuten',
        'second' => 'Sekunden',
    ),
    'es' => array(
        'title' => 'Mantenimiento del sitio',
        'heading' => '¡Volveremos pronto!',
        'text' => '¡Estamos mejorando algunas cosas para ti! Mientras tanto, siéntete libre de <a href="' . $contact_link . '">unirte a nosotros en Discord</a> para charlar o para obtener la asistencia que necesitas. Estaremos operativos en un instante, y la página se recargará automáticamente al final de la cuenta regresiva a continuación.',
        'team' => '&mdash; El equipo',
        'day' => 'Días',
        'hour' => 'Horas',
        'minute' => 'Minutos',
        'second' => 'Segundos',
    ),
    'zh' => array(
        'title' => '网站维护',
        'heading' => '我们很快就会回来!',
        'text' => '我们正在为您改善一些事物!同时,欢迎您<a href="' . $contact_link . '">加入我们的Discord</a>进行交流或获取您所需的帮助。我们将很快恢复运行,页面将在下方倒计时结束时自动刷新。',
        'team' => '&mdash; 团队',
        'day' => '天',
        'hour' => '小时',
        'minute' => '分钟',
        'second' => '秒',
    ),
    'pt' => array(
        'title' => 'Manutenção do Site',
        'heading' => 'Voltaremos em breve!',
        'text' => 'Estamos aprimorando algumas coisas para você! Enquanto isso, sinta-se à vontade para <a href="' . $contact_link . '">se juntar a nós no Discord</a> para conversar ou obter a ajuda que precisa. Estaremos de volta num piscar de olhos, e a página será recarregada automaticamente ao final da contagem abaixo.',
        'team' => '&mdash; O time',
        'day' => 'Dias',
        'hour' => 'Horas',
        'minute' => 'Minutos',
        'second' => 'Segundos',
    ),
);

// Set the protocol
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ?? '';
if (!in_array($protocol, array('HTTP/1.1', 'HTTP/2', 'HTTP/2.0'), true)) {
    $protocol = 'HTTP/1.0';
}

// Set the status code for crawlers like googlebot...
header("$protocol 503 Service Unavailable", true, 503);
header('Content-Type: text/html; charset=utf-8');
header('Retry-After: ' . $time_to_wait);
?>

<!doctype html>
<html lang="en">
<head>
    <title><?php echo $site_title . ' - ' . $translations[$lang]['title']; ?></title>
    <meta charset="utf-8">
    <meta name="robots" content="noindex">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        html body {
            text-align: center;
            padding: 20px;
            font: 20px Helvetica, sans-serif;
            color: #333;
            background-color: #ffffff;
        }
        @media (min-width: 768px) {
            html body {
                padding-top: 150px;
            }
        }
        h1 {
            font-size: 50px;
        }
        article {
            display: block;
            text-align: left;
            max-width: 650px;
            margin: 0 auto;
        }
        body a {
            color: #dc8100;
            text-decoration: none;
        }
        body a:hover {
            color: #333;
            text-decoration: none;
        }
        @media (prefers-color-scheme: dark) {
            html body {
                color: #efe8e8;
                background-color: #2e2929;
            }
            body a {
                color: #dc8100;
            }
            body a:hover {
                color: #efe8e8;
            }
        }
    </style>
</head>
<body>
<article>
    <h1><?php echo $translations[$lang]['heading']; ?></h1>
    <div>
        <p><?php echo $translations[$lang]['text']; ?></p>
        <p><?php echo $translations[$lang]['team']; ?></p>
    </div>
    <div style="display: flex; flex-direction: row; justify-content: space-between;">
        <p class="day"></p>
        <p class="hour"></p>
        <p class="minute"></p>
        <p class="second"></p>
    </div>
    <div class="pyro">

    </div>
</article>

<script>
    const stringDate = new Date(Date.now() + <?php echo $time_to_wait ?> * 1000).toLocaleString();
    const countDay = new Date(stringDate); //format: MM/DD/YYYY HH:MM:SS
    const countDown = () => {
            const now = new Date();
            const counter = countDay - now;
            const second = 1000;
            const minute = second * 60;
            const hour = minute * 60;
            const day = hour * 24;
            const textDay = Math.floor(counter / day);
            const textHour = Math.floor((counter % day) / hour);
            const textMinute = Math.floor((counter % hour) / minute);
            const textSecond = Math.floor((counter % minute) / second);

            if (textSecond < 0) {
              theDay = 0;
              theHour = 0;
              theMinute = 0;
              theSecond = 0;

              window.location.reload();
            } else {
              theDay = textDay;
              theHour = textHour;
              theMinute = textMinute;
              theSecond = textSecond;
            }
            document.querySelector(".day").innerText = theDay + ' Days';
            document.querySelector(".hour").innerText = theHour + ' Hours';
            document.querySelector(".minute").innerText = theMinute + ' Minutes';
            document.querySelector(".second").innerText = theSecond + ' Seconds';
        }
        countDown();
        setInterval(countDown, 1000);
</script>
</body>
</html>

@hmunyeku
Copy link

hmunyeku commented Jun 2, 2024

Dear, Here a version with :

  • Logo of the company
  • contact link could be mail or website
  • style, dark and light mode
  • Social links
<?php
$time_to_wait = 388800; // in seconds
$site_title = '';
$contact_link = ''; // Exemple: 'xx@xx.xx', 'https://xx.xx.xx', 'https://discord.com/invite/xxx'
$logo_path = 'path/to/logo.png'; // Spécifiez le chemin du logo
$logo_link = 'https://xx.xx.xx'; // Spécifiez le lien du logo
$facebook_link = 'https://www.facebook.com/xx'; // Spécifiez le lien Facebook
$linkedin_link = 'https://www.linkedin.com/company/xx/'; // Spécifiez le lien LinkedIn
$whatsapp_link = 'https://wa.me/xx'; // Spécifiez le lien WhatsApp
$legal_info = 'xx (c) xx'; // Informations légales
$redirect_url = 'https://xx.xx.xx'; // URL de redirection après le décompte
$gears_gif_path = 'path/to/gears.gif'; // Spécifiez le chemin du GIF des engrenages tournants

// Détecter le type de lien de contact
if (strpos($contact_link, '@') !== false) {
    $contact_href = 'mailto:' . $contact_link;
} elseif (strpos($contact_link, 'http') === 0) {
    $contact_href = $contact_link;
} else {
    $contact_href = 'http://' . $contact_link;
}

// Get the user's preferred languages from the Accept-Language header
$languages = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);

// Set the default language to English
$lang = 'en';

// Loop through the user's preferred languages and check if we have a translation available
foreach ($languages as $language) {
    $language = strtolower(substr($language, 0, 2));
    if (in_array($language, array('en', 'ar', 'fr', 'de', 'es', 'zh', 'pt'))) {
        $lang = $language;
        break;
    }
}

// Set the content-language header to the selected language
header("Content-Language: $lang");

// Check if the logo exists
$logo_exists = !empty($logo_path) && file_exists($logo_path);

// Translations object
$translations = array(
    'en' => array(
        'title' => 'Site Maintenance',
        'heading' => 'We\'ll be back soon!',
        'text' => 'We\'re just sprucing things up a bit! In the meantime, feel free to <a href="' . $contact_href . '">join us on our customer support portal</a> for a chat or to get any assistance you need. We\'ll be up and running in just a moment, and the page will automatically refresh at the end of the countdown below.',
        'team' => '&mdash; The Team',
        'day' => 'Days',
        'hour' => 'Hours',
        'minute' => 'Minutes',
        'second' => 'Seconds',
    ),
    'ar' => array(
        'title' => 'صيانة الموقع',
        'heading' => 'سنعود قريبا!',
        'text' => 'نحن نعمل على تحسين الموقع لك! في هذه الأثناء، لا تتردد في <a href="' . $contact_href . '">الانضمام إلينا على بوابة دعم العملاء الخاصة بنا</a> للدردشة أو للحصول على المساعدة التي تحتاجها. سنعود للعمل في لحظات قليلة، وسيتم تحديث الصفحة تلقائياً عند انتهاء العد التنازلي أدناه.',
        'team' => '&mdash; فريق العمل',
        'day' => 'أيام',
        'hour' => 'ساعات',
        'minute' => 'دقائق',
        'second' => 'ثواني',
    ),
    'fr' => array(
        'title' => 'Maintenance du site',
        'heading' => 'Nous reviendrons bientôt!',
        'text' => 'Nous apportons juste quelques améliorations! En attendant, n\'hésitez pas à <a href="' . $contact_href . '">nous rejoindre sur notre portail support client</a> pour discuter ou obtenir l\'aide dont vous avez besoin. Nous serons de retour en un instant, et la page se rafraîchira automatiquement à la fin du compte à rebours ci-dessous.',
        'team' => '&mdash; L\'équipe',
        'day' => 'Jours',
        'hour' => 'Heures',
        'minute' => 'Minutes',
        'second' => 'Secondes',
    ),
    'de' => array(
        'title' => 'Wartung der Website',
        'heading' => 'Wir sind bald zurück!',
        'text' => 'Wir verbessern gerade ein paar Dinge für dich! In der Zwischenzeit kannst du dich gerne <a href="' . $contact_href . '">uns auf unserem Kunden-Support-Portal anschließen</a>, um zu chatten oder um die Hilfe zu erhalten, die du benötigst. Wir sind in Kürze wieder da, und die Seite wird am Ende des Countdowns unten automatisch aktualisiert.',
        'team' => '&mdash; Das Team',
        'day' => 'Tage',
        'hour' => 'Stunden',
        'minute' => 'Minuten',
        'second' => 'Sekunden',
    ),
    'es' => array(
        'title' => 'Mantenimiento del sitio',
        'heading' => '¡Volveremos pronto!',
        'text' => '¡Estamos mejorando algunas cosas para ti! Mientras tanto, siéntete libre de <a href="' . $contact_href . '">unirte a nosotros en nuestro portal de soporte al cliente</a> para charlar o para obtener la asistencia que necesitas. Estaremos operativos en un instante, y la página se recargará automáticamente al final de la cuenta regresiva a continuación.',
        'team' => '&mdash; El equipo',
        'day' => 'Días',
        'hour' => 'Horas',
        'minute' => 'Minutos',
        'second' => 'Segundos',
    ),
    'zh' => array(
        'title' => '网站维护',
        'heading' => '我们很快就会回来!',
        'text' => '我们正在为您改善一些事物!同时,欢迎您<a href="' . $contact_href . '">加入我们的客户支持门户</a>进行交流或获取您所需的帮助。我们将很快恢复运行,页面将在下方倒计时结束时自动刷新。',
        'team' => '&mdash; 团队',
        'day' => '天',
        'hour' => '小时',
        'minute' => '分钟',
        'second' => '秒',
    ),
    'pt' => array(
        'title' => 'Manutenção do Site',
        'heading' => 'Voltaremos em breve!',
        'text' => 'Estamos aprimorando algumas coisas para você! Enquanto isso, sinta-se à vontade para <a href="' . $contact_href . '">se juntar a nós em nosso portal de suporte ao cliente</a> para conversar ou obter a ajuda que precisa. Estaremos de volta num piscar de olhos, e a página será recarregada automaticamente ao final da contagem abaixo.',
        'team' => '&mdash; O time',
        'day' => 'Dias',
        'hour' => 'Horas',
        'minute' => 'Minutos',
        'second' => 'Segundos',
    ),
);

// Set the protocol
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ?? '';
if (!in_array($protocol, array('HTTP/1.1', 'HTTP/2', 'HTTP/2.0'), true)) {
    $protocol = 'HTTP/1.0';
}

// Set the status code for crawlers like googlebot...
header("$protocol 503 Service Unavailable", true, 503);
header('Content-Type: text/html; charset=utf-8');
header('Retry-After: ' . $time_to_wait);
?>

<!doctype html>
<html lang="en">
<head>
    <title><?php echo $site_title . ' - ' . $translations[$lang]['title']; ?></title>
    <meta charset="utf-8">
    <meta name="robots" content="noindex">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="icon" href="path/to/favicon.ico" type="image/x-icon">
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
    <style>
        body {
            font-family: 'Roboto', sans-serif;
            color: #333;
            background-color: #f8f9fa;
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            text-align: center;
        }
        .container {
            background: white;
            padding: 40px;
            border-radius: 10px;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
            max-width: 600px;
            width: 100%;
            margin: 20px;
        }
        h1 {
            font-size: 36px;
            color: #dc3545;
            margin-bottom: 20px;
        }
        p {
            font-size: 16px;
            line-height: 1.5;
            margin: 20px 0;
        }
        a {
            color: #007bff;
            text-decoration: none;
        }
        a:hover {
            text-decoration: underline;
        }
        .countdown {
            display: flex;
            justify-content: center;
            margin-top: 20px;
        }
        .countdown div {
            margin: 0 10px;
            text-align: center;
        }
        .countdown div span {
            display: block;
            font-size: 30px;
            font-weight: bold;
            animation: pulse 1s infinite;
        }
        .countdown div label {
            font-size: 18px;
            color: #777;
        }
        @keyframes pulse {
            0% { transform: scale(1); }
            50% { transform: scale(1.05); }
            100% { transform: scale(1); }
        }
        img.logo {
            max-width: 100px;
            margin-bottom: 20px;
        }
        .social-icons {
            margin-top: 20px;
        }
        .social-icons a {
            margin: 0 10px;
            color: #007bff;
            text-decoration: none;
            font-size: 24px;
        }
        .social-icons a:hover {
            color: #0056b3;
        }
        footer {
            margin-top: 20px;
            font-size: 12px;
            color: #777;
        }
        @media (prefers-color-scheme: dark) {
            body {
                background-color: #2e2e2e;
                color: #e0e0e0;
            }
            .container {
                background: #3e3e3e;
                color: #e0e0e0;
            }
            a {
                color: #79b8ff;
            }
            a:hover {
                color: #d1eaff;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <?php if ($logo_exists): ?>
            <a href="<?php echo $logo_link; ?>"><img src="<?php echo $logo_path; ?>" alt="Logo" class="logo"></a>
        <?php endif; ?>
        <h1><?php echo $translations[$lang]['heading']; ?></h1>
        <div>
            <p><?php echo $translations[$lang]['text']; ?></p>
            <p><?php echo $translations[$lang]['team']; ?></p>
        </div>
        <div class="countdown">
            <div>
                <span class="day"></span>
                <label><?php echo $translations[$lang]['day']; ?></label>
            </div>
            <div>
                <span class="hour"></span>
                <label><?php echo $translations[$lang]['hour']; ?></label>
            </div>
            <div>
                <span class="minute"></span>
                <label><?php echo $translations[$lang]['minute']; ?></label>
            </div>
            <div>
                <span class="second"></span>
                <label><?php echo $translations[$lang]['second']; ?></label>
            </div>
        </div>
        <?php if ($facebook_link || $linkedin_link || $whatsapp_link): ?>
            <div class="social-icons">
                <?php if ($facebook_link): ?>
                    <a href="<?php echo $facebook_link; ?>" target="_blank"><i class="fab fa-facebook"></i></a>
                <?php endif; ?>
                <?php if ($linkedin_link): ?>
                    <a href="<?php echo $linkedin_link; ?>" target="_blank"><i class="fab fa-linkedin"></i></a>
                <?php endif; ?>
                <?php if ($whatsapp_link): ?>
                    <a href="<?php echo $whatsapp_link; ?>" target="_blank"><i class="fab fa-whatsapp"></i></a>
                <?php endif; ?>
            </div>
        <?php endif; ?>
        <footer>
            <?php echo $legal_info; ?>
        </footer>
    </div>

    <script>
        const stringDate = new Date(Date.now() + <?php echo $time_to_wait ?> * 1000).toLocaleString();
        const countDay = new Date(stringDate); // format: MM/DD/YYYY HH:MM:SS
        const countDown = () => {
            const now = new Date();
            const counter = countDay - now;
            const second = 1000;
            const minute = second * 60;
            const hour = minute * 60;
            const day = hour * 24;
            const textDay = Math.floor(counter / day);
            const textHour = Math.floor((counter % day) / hour);
            const textMinute = Math.floor((counter % hour) / minute);
            const textSecond = Math.floor((counter % minute) / second);

            if (textSecond < 0) {
                window.location.href = '<?php echo $redirect_url; ?>';
            } else {
                document.querySelector(".day").innerText = textDay;
                document.querySelector(".hour").innerText = textHour;
                document.querySelector(".minute").innerText = textMinute;
                document.querySelector(".second").innerText = textSecond;
            }
        }
        countDown();
        setInterval(countDown, 1000);
    </script>
</body>
</html>

@rexyOnery
Copy link

Here is the conversion from php to .NET Core Pages | C#

@page
@model IndexModel
@{
// Get the user's preferred languages from the Accept-Language header
string[] languages = HttpContext.Request.Headers.AcceptLanguage.ToString().Split(',');

// Set the default language to English
string lang = "en";

// Loop through the user's preferred languages and check if we have a translation available
foreach (string language in languages)
{
    string shortLanguage = language.Substring(0, 2).ToLower();
    if (new string[] { "en", "ar", "fr", "es", "zh", "pt" }.Contains(shortLanguage))
    {
        lang = shortLanguage;
        break;
    }
}

// Set the content-language header to the selected language
HttpContext.Response.Headers.Append("Content-Language", lang);

// Translations object
Dictionary<string, Dictionary<string, string>> translations = new Dictionary<string, Dictionary<string, string>>

{
{ "en", new Dictionary<string, string>
{

        { "title", "Site Maintenance" },
        { "heading", "We'll be back soon!" },
        { "text", "Sorry for the inconvenience but we're performing some maintenance at the moment. You can always <a href=\"#\">contact us</a>, otherwise we'll be back online shortly!" },
        { "team", "&mdash; The Team" },
        { "day", "Days" },
        { "hour", "Hours" },
        { "minute", "Minutes" },
        { "second", "Seconds" }
    }
},
{ "ar", new Dictionary<string, string>
    {
         
        { "title", "صيانة الموقع" },
        { "heading", "سنعود قريبا!" },
        { "text", "نعتذر عن الإزعاج الذي قد يسببه الصيانة الحالية للموقع. في حال كان لديك أي احتياجات يمكنك الاتصال بنا على الفور <a href=\"#\">بريدنا الإلكتروني</a>، وفي غير ذلك فسنعود على المدى القريب!" },
        { "team", "&mdash; فريق العمل" },
        { "day", "أيام" },
        { "hour", "ساعات" },
        { "minute", "دقائق" },
        { "second", "ثواني" }
    }
},
{ "fr", new Dictionary<string, string>
    {
         
        { "title", "Entretien des sites" },
        { "heading", "Nous reviendrons bientôt!" },
        { "text", "Désolé pour le désagrément mais nous effectuons actuellement une maintenance.. If you need to you can alwaysSi vous en avez besoin, vous pouvez toujours <a href=\"#\">nous contacter</a>, sinon nous serons de nouveau en ligne sous peu !" },
        { "team", "&mdash; L'équipe" },
        { "day", "Jours" },
        { "hour", "Heures" },
        { "minute", "Minutes" },
        { "second", "Seconds" }
    }
},
{ "es", new Dictionary<string, string>
    {
         
        { "title", "Mantenimiento del sitio" },
        { "heading", "Volveremos pronto!" },
        { "text", "Disculpe las molestias pero estamos realizando algunas tareas de mantenimiento en este momento. Si lo necesita, siempre puede <a href=\"#\">contáctenos</a>; de lo contrario, volveremos a estar en línea en breve." },
        { "team", "&mdash; El equipo" },
        { "day", "Días" },
        { "hour", "Horas" },
        { "minute", "Minutos" },
        { "second", "Segundos" }
    }
},
{ "zh", new Dictionary<string, string>
    {
         
        { "title", "网站维护" },
        { "heading", "我们很快就回来!" },
        { "text", "抱歉造成不便,但我们目前正在进行维护. 您可以随时<a href=\"#\">联系我们</a>,否则我们很快就会恢复在线!" },
        { "team", "&mdash; 团队" },
        { "day", "天" },
        { "hour", "小时" },
        { "minute", "分钟" },
        { "second", "秒" }
    }
},
{ "pt", new Dictionary<string, string>
    {
         
        { "title", "Página em manutenção" },
        { "heading", "Voltaremos em breve!" },
        { "text", "Desculpe pelo transtorno, mas estamos realizando algumas manutenções no momento. Você sempre pode <a href=\"#\">entre em contato conosco</a>, caso contrário estaremos online novamente em breve!" },
        { "team", "&mdash; O time" },
        { "day", "Dias" },
        { "hour", "Horas" },
        { "minute", "Minutos" },
        { "second", "Segundos" }
    }
},
// Add translations for other languages here

};

// Set the protocol
string protocol = HttpContext.Request.Protocol ?? "";
if (!new string[] { "HTTP/1.1", "HTTP/2", "HTTP/2.0" }.Contains(protocol))
{
    protocol = "HTTP/1.0";
}

 
 
ViewData["Title"] = translations[lang]["title"];
ViewData["Heading"] = translations[lang]["heading"];
ViewData["Text"] = translations[lang]["text"];
ViewData["Team"] = translations[lang]["team"];

ViewData["Day"] = translations[lang]["day"];
ViewData["Hour"] = translations[lang]["hour"];
ViewData["Minutes"] = translations[lang]["minute"];
ViewData["Second"] = translations[lang]["second"];

}

<!doctype html>

<title></title> <style> html body { text-align: center; padding: 20px; font: 20px Helvetica, sans-serif; color: #333; background-color: #ffffff; } @@media (min-width: 768px) { html body { padding-top: 150px; } } h1 { font-size: 50px; } article { display: block; text-align: left; max-width: 650px; margin: 0 auto; } body a { color: #dc8100; text-decoration: none; } body a:hover { color: #333; text-decoration: none; } @@media (prefers-color-scheme: dark) { html body { color: #efe8e8; background-color: #2e2929; } body a { color: #dc8100; } body a:hover { color: #efe8e8; } } </style>
<h1> @ViewData["Heading"] </h1>
<div>

    <p>@Html.Raw(ViewData["Text"])</p>
    <p>@Html.Raw(ViewData["Team"])</p>
</div>
<div style="display: flex; flex-direction: row; justify-content: space-between;">
    <p><span class="day"></span> @ViewData["Day"]</p>
    <p><span class="hour"></span> @ViewData["Hour"]</p>
    <p><span class="minute"></span> @ViewData["Minutes"]</p>
    <p><span class="second"></span> @ViewData["Second"]</p>
</div>
<script>
const countDown = () => {
    const countDay = new Date("06/31/2024"); // please indicate launch date (mm/dd/YYYY) :)
    const now = new Date();
    const counter = countDay - now;
    const second = 1000;
    const minute = second * 60;
    const hour = minute * 60;
    const day = hour * 24;
    const textDay = Math.floor(counter / day);
    const textHour = Math.floor((counter % day) / hour);
    const textMinute = Math.floor((counter % hour) / minute);
    const textSecond = Math.floor((counter % minute) / second);

    if (textSecond < 0) {
        textDay = "0";
        textHour = "0";
        textMinute = "0";
        textSecond = "0";

    } else {
        theDay = textDay;
        theHour = textHour;
        theMinute = textMinute;
        theSecond = textSecond;
    }
    document.querySelector(".day").innerText = textDay;
    document.querySelector(".hour").innerText = textHour;
    document.querySelector(".minute").innerText = textMinute;
    document.querySelector(".second").innerText = textSecond;
}
countDown();
setInterval(countDown, 1000);
</script>

@sammybammy52
Copy link

<!doctype html>

<title>Site Maintenance</title> <style> body { text-align: center; padding: 20px; font: 20px Helvetica, sans-serif; color: #efe8e8; } @media (min-width: 768px){ body{ padding-top: 150px; } } h1 { font-size: 50px; } article { display: block; text-align: left; max-width: 650px; margin: 0 auto; } a { color: #dc8100; text-decoration: none; } a:hover { color: #efe8e8; text-decoration: none; } </style>

We’ll be back soon!

Sorry for the inconvenience but we’re performing some maintenance at the moment. If you need to you can always contact us, otherwise we’ll be back online shortly!

— The Team

    </div>
    <div style="display: flex; flex-direction: row; justify-content: space-between;">
        <p class="day"></p>
        <p class="hour"></p>
        <p class="minute"></p>
        <p class="second"></p>
    </div>
</article>
<script>
    const countDown = () => {
        const countDay = new Date('December 28, 2022 00:00:00');
        const now = new Date();
        const counter = countDay - now;
        const second = 1000;
        const minute = second * 60;
        const hour = minute * 60;
        const day = hour * 24;
        const textDay = Math.floor(counter / day);
        const textHour = Math.floor((counter % day) / hour);
        const textMinute = Math.floor((counter % hour) / minute);
        const textSecond = Math.floor((counter % minute) / second)
        document.querySelector(".day").innerText = textDay + ' Days';
        document.querySelector(".hour").innerText = textHour + ' Hours';
        document.querySelector(".minute").innerText = textMinute + ' Minutes';
        document.querySelector(".second").innerText = textSecond + ' Seconds';
    }
    setInterval(countDown, 1000);
</script>

thanks bro

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment