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>
@Alphaegen
Copy link

I recommend adding countDown(); before setInterval(countDown, 1000); if you want the timer to show immediately.

@aminghs
Copy link

aminghs commented Jun 13, 2022

@Alphaegen Thanks for your recommendation

@mgollo
Copy link

mgollo commented Jul 28, 2022

Thank you, we are using a slightly adapted version of this now!

@doxt3r
Copy link

doxt3r commented Aug 19, 2022

If you are using php/wordpress use the following code in the header to inform crawlers (you need to adapt it for non wp sites):

<?php
$protocol = wp_get_server_protocol();
header( "$protocol 503 Service Unavailable", true, 503 );
header( 'Content-Type: text/html; charset=utf-8' );
header( 'Retry-After: 30' );
?>

@doxt3r
Copy link

doxt3r commented Aug 24, 2022

Update for pure php website:

<?php
$protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : '';
if ( ! in_array( $protocol, array( 'HTTP/1.1', 'HTTP/2', 'HTTP/2.0' ), true ) ) {
   $protocol = 'HTTP/1.0';
}
header( "$protocol 503 Service Unavailable", true, 503 );
header( 'Content-Type: text/html; charset=utf-8' );
header( 'Retry-After: 30' );
?>

@nam2long
Copy link

nam2long commented Nov 5, 2022

I added all the above changes for Dark Mode + Javascript count Down + Php code above with CSS 3 & HTML 5 Compliance...remove everything in-between <script> and </script> if you don't want the countdown.

<?php
$protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : '';
if ( ! in_array( $protocol, array( 'HTTP/1.1', 'HTTP/2', 'HTTP/2.0' ), true ) ) {
   $protocol = 'HTTP/1.0';
}
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>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: #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>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>
        <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';
        }
        countDown();
        setInterval(countDown, 1000);
    </script>
  </body>
</html>

@nam2long
Copy link

nam2long commented Nov 5, 2022

Here is the Light version (non-Dark Mode).. .difference is #FFFFFFfor background color, and #333 for color tags in body and a:hover

<?php
$protocol = isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : '';
if ( ! in_array( $protocol, array( 'HTTP/1.1', 'HTTP/2', 'HTTP/2.0' ), true ) ) {
   $protocol = 'HTTP/1.0';
}
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>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; }
    </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>
        <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';
        }
        countDown();
        setInterval(countDown, 1000);
    </script>
  </body>
</html>

@dmisljen
Copy link

dmisljen commented Nov 9, 2022

Super helpfull for a quick notice with all the basics. Thanks!

@mikelibu
Copy link

its great, thanks very much, used it in my web. Regards!

@MrCyjaneK
Copy link

thanks (again)

@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

@xavi7th
Copy link

xavi7th commented Sep 12, 2024

For those that want an idea what this looks like before implementation. Here are some screenshots

THE OG post
Screenshot 2024-09-12 at 12 21 44

THE OG Dark mode version
Screenshot 2024-09-12 at 12 22 17

THE OG Version with a countdown
Screenshot 2024-09-12 at 12 24 06

Then here is an updated version with hopefully all the changes postulated for PHP

<?php http_response_code(500); ?>

<?php
$time_to_wait = 7200; // in seconds
$site_title = 'PHKHotdeals';
$contact_link = 'https://t.me/leinad8th'; // Exemple: 'xx@xx.xx', 'https://xx.xx.xx', 'https://discord.com/invite/xxx'
$logo_path = './logo-light.png'; // Spécifiez le chemin du logo
$logo_link = 'mailto:hello@phktopdeals.com'; // Spécifiez le lien du logo
$facebook_link = 'https://www.facebook.com/phktopdeals'; // Spécifiez le lien Facebook
$linkedin_link = 'https://www.linkedin.com/in/phktopdeals/'; // Spécifiez le lien LinkedIn
$whatsapp_link = 'https://wa.me/2348034411661'; // Spécifiez le lien WhatsApp
$legal_info = 'Copyright (c) 2024'; // Informations légales
$redirect_url = 'https://phktopdeals.com'; // URL de redirection après le décompte
$gears_gif_path = 'path/to/gears.gif'; // Spécifiez le chemin du GIF des engrenages tournants
$font_color = '#dc8100';

// 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; PHKHotdeals 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">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <link rel="icon" href="./logo-dark.png" type="image/png">
    <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: <?php echo $font_color ?>;
            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>

Screenshot Prefers Light Mode
Screenshot 2024-09-12 at 12 39 11

Screenshot Prefers Dark Mode
Screenshot 2024-09-12 at 12 39 26

Thanks to all that made this very simple design very robust.

@Baliar93
Copy link

We can make it easier and safer to accurately diagnose and treat patients with our custom DICOM solutions. Hire professionals who are certified, experienced, and ready to build your next product.

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