Cuándo tenemos una tarea de mantenimiento que hacer en una web, y su realización va a suponer un corte del servicio temporal, nada mejor que entrar en el conocido como «modo mantenimiento», que básicamente consiste en mostrar al usuario un mensaje informándole de por qué no puede acceder a la web de forma normal.

En este mensaje es importante que el usuario comprenda que no se trata de ningún error y que no hay nada mal, sino que se trata de un corte temporal que se ha tenido que hacer sin más remedio para realizar alguna tarea de mantenimiento o actualización que no podía ser realizada sin afectar a la continuidad del servicio.

Precisamente por ser tareas de mantenimiento, su realización debería ser un evento programado y planificado con antelación, salvo situaciones de urgencia que no se puedan preveer. Así, podremos tenerlo todo listo para hacerlo rápido y elegir un día y una hora de poco tráfico; incluso podemos avisar a los usuarios previamente de las horas previstas para el corte.

Lamentablemente todo esto no es suficiente para los motores de búsqueda. A ellos tenemos que informarle de una forma diferente: utilizando los códigos de estado HTTP con los que respondemos cuándo intentan acceder a nuestra web.

Redirección 503

Para entrar en «modo mantenimiento» es bastante común que se haga una redirección 302 de todo el tráfico hacia una página especial que contiene el mensaje para nuestros usuarios.

Pero el código de estado 302 indica que el «contenido ha sido movido a otra URL de forma temporal». Y este NO es el caso. La página a la que se redirecciona no es una localización temporal del contenido.

En su lugar se debería utilizar el código de estado 503 – Service Unavailable. Si leemos las especificaciones del protocolo HTTP, el código de estado 503 significa exactamente lo siguiente:

The server is currently unable to handle the request due to a temporary overloading or maintenance of the server

RFC2616 - HTTP/1.1 Status code definitions

Si lo traducimos, el código de estado 503 indica que no se puede responder a la solicitud debido a una sobrecarga temporal del servidor o, aquí lo importante, a tareas de mantenimiento. Es el código de estado perfecto para este caso.

Si puede implementar con .htaccess de este modo:

RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} !=503
# Nota: en realidad, técnicamente, se realiza una reescritura, no una redirección
RewriteRule !^/mantenimiento.html$ https://ejemplo.com/mantenimiento.html [R=503,L]
ErrorDocument 503 /mantenimiento.html

Cabecera Retry-After

Además de avisar a los usuarios del motivo del corte, podemos avisarles de cuándo está previsto que la web vuelva a la normalidad. Este mismo mensaje se lo podemos transmitir a los robots y buscadores con la cabecera HTTP Retry-After, indicando la fecha y la hora en la que se espera hayan terminado las tareas de mantenimiento.

De forma alternativa a una fecha y hora concreta, en un formato HTTP-date válido, se puede indicar un número de segundos que el cliente debería esperar desde la hora de la última visita antes de intentar acceder otra vez.

El Retry-After en .htaccess, combinado con la redirección 503, tendría un aspecto similar a este:

Header set Retry-After "Sat, 18 Mar 2021 18:27:00 GMT"
RewriteEngine On
RewriteCond %{ENV:REDIRECT_STATUS} !=503
RewriteRule !^/mantenimiento.html$ https://ejemplo.com/mantenimiento.html [R=503,L]
ErrorDocument 503 /mantenimiento.html

También se pueden establecer estas cabeceras desde un srcipt PHP con la función header():

header( 'Retry-After: Sat, 18 Mar 2021 18:27:00 GMT' );
header( 'HTTP/1.1 503 Service Temporarily Unavailable', true, 503 );

El «modo en construcción», aunque sea conceptualmente diferente al «modo mantenimiento», se puede tratar igual en lo que respecta a las cabeceras HTTP. Este método sería igualmente válido para entrar en modo «en construcción».

En cualquier caso, nunca se debe utilizar una redirección 301. Un código de estado 200 OK tampoco es recomendable. Ambos pueden hacer que se indexen contenidos y URLs erróneas.