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>
@00pp
Copy link

00pp commented Mar 1, 2022

Thank you! Successfully used it on datei.wiki

Copy link

ghost commented Mar 13, 2022

@MouseMoosz
Thanks!!!

@clementbo50
Copy link

merci bocoup c pour mon projet gsb youpi

@aminghs
Copy link

aminghs commented Mar 29, 2022

With simple count down:

<!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: #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>
  </head>
  <body bgcolor="2e2929">
    <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';
        }
        setInterval(countDown, 1000);
    </script>
  </body>
</html>

@isantiago95
Copy link

awesome!!
Thanks for that, it helps a lot when need a simple template

@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>

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