Skip to content

Tela de Manutenção

🔍 Preview

A tela de manutenção é exibida automaticamente quando o servidor retorna HTTP 503, substituindo qualquer layout normal da aplicação por uma tela amigável ao usuário.


O que é a tela de manutenção?

A tela de manutenção é um layout especial que assume o controle visual da aplicação quando o backend está indisponível (resposta HTTP 503 Service Unavailable).

Ela é controlada pelo CoreLayout.vue, que verifica o status da navegação antes de decidir qual layout renderizar. Se o status for 503, o MaintenanceLayout é ativado — independente da rota acessada.

Quando usar?

Use a tela de manutenção quando:

  • O servidor da loja precisa ficar offline temporariamente para deploys ou atualizações
  • Você quer exibir uma mensagem amigável em vez de uma tela de erro genérica do browser
  • A loja precisa comunicar ao cliente que voltará em breve
  • Não é necessário nenhuma configuração no frontend para acionar a tela — basta o servidor retornar 503.

    Implementação

    A implementação envolve 4 arquivos:

    1. O componente MaintenanceLayout.vue em src/layouts/MaintenanceLayout.vue:

    1<script setup lang="ts"></script>
    2
    3<template>
    4 <div class="maintenance-layout">
    5 <h1>Uma pausa para um café e algumas melhorias.</h1>
    6 <p>Nosso site está se atualizando para te atender melhor. Voltamos logo!</p>
    7
    8 <!-- Logo da loja -->
    9 <svg ...></svg>
    10 </div>
    11</template>
    12
    13<style scoped>
    14.maintenance-layout {
    15 display: flex;
    16 justify-content: center;
    17 align-items: center;
    18 flex-direction: column;
    19 gap: 8px;
    20
    21 width: 100%;
    22 height: 100vh;
    23
    24 text-align: center;
    25}
    26
    27/<em> Efeito typewriter no título (ajuste steps() para o nº de caracteres) </em>/
    28h1 {
    29 font-size: 32px;
    30 overflow: hidden;
    31 white-space: nowrap;
    32 border-right: 3px solid transparent;
    33 width: 0;
    34 animation:
    35 blink-cursor 0.5s step-end infinite,
    36 write-title 3s steps(19) forwards;
    37}
    38
    39/<em> Texto aparece depois que o título termina </em>/
    40p {
    41 font-size: 18px;
    42 overflow: hidden;
    43 white-space: nowrap;
    44 border-right: 3px solid transparent;
    45 width: 0;
    46 animation:
    47 blink-cursor 0.5s step-end infinite,
    48 write-text 3s steps(39) forwards;
    49 animation-delay: 3s;
    50}
    51
    52@keyframes write-title {
    53 from { width: 0; border-right-color: #000; }
    54 to { width: 38ch; border-right-color: transparent; }
    55}
    56
    57@keyframes write-text {
    58 from { width: 0; border-right-color: #000; }
    59 to { width: 57ch; border-right-color: #000; }
    60}
    61
    62@keyframes blink-cursor {
    63 from, to { border-right-color: transparent; }
    64 50% { border-right-color: #000; }
    65}
    66</style>

    2. Registro do layout globalmente em main.ts

    1import DefaultLayout from '@/layouts/DefaultLayout.vue';
    2import MaintenanceLayout from '@/layouts/MaintenanceLayout.vue'; // Layout de manutenção
    3
    4const app = createApp(App);
    5
    6app.component('DefaultLayout', DefaultLayout);
    7app.component('MaintenanceLayout', MaintenanceLayout); // Layout de manutenção

    3. Declarar o tipo no RouteMeta em src/router/routes.ts

    1declare module 'vue-router' {
    2 interface RouteMeta {
    3 layout: 'DefaultLayout' | 'MaintenanceLayout';
    4 }
    5}

    4. Ativar a detecção de 503 no CoreLayout.vue O CoreLayout.vue já implementa a lógica de detecção. Verifique se o bloco abaixo existe:

    1const layout = computed(() => {
    2 const navigationResources = performance.getEntriesByType(
    3 'navigation',
    4 )[0] as PerformanceResourceTiming;
    5
    6 if (navigationResources?.responseStatus === 503) return 'MaintenanceLayout'; // 👈
    7
    8 if (currentRoute.value.meta.layout) {
    9 return currentRoute.value.meta.layout;
    10 }
    11
    12 return 'DefaultLayout';
    13});

    Essa lógica usa a Navigation Timing API para ler o status HTTP real da navegação. Se o servidor retornar 503, o MaintenanceLayout é renderizado automaticamente — sem redirecionamento de rota.

    Personalizando o conteúdo

    Alterando os textos

    Edite diretamente o template em MaintenanceLayout.vue:

    1<h1>Sua mensagem aqui.</h1>
    2<p>Sua descrição aqui.</p>

    Após mudar os textos, atualize os valores de steps() e width nas animações para refletir o novo número de caracteres:

    ElementoPropriedadeComo calcular
    h1width: XchUse o mesmo N (ou ligeiramente maior para folga)
    psteps(N)Conte os caracteres do texto (incluindo espaços)
    pwidth: XchUse o mesmo N (ou ligeiramente maior para folga)
    panimation-delayDeve ser igual à duração da animação do h1
    Exemplo: o texto "Voltamos em breve!" tem 18 caracteres → steps(18) e width: 20ch.

    Desativando o efeito typewriter

    Se preferir exibir os textos sem animação, substitua os estilos de h1 e p por:

    1h1 { font-size: 32px; }
    2p { font-size: 18px; }

    ⚠️ Pontos de atenção

  • O layout não é ativado por rota — ele é ativado pelo status HTTP 503 na resposta de navegação. Isso significa que funciona mesmo se o usuário acessar qualquer URL da loja.
  • A detecção usa performance.getEntriesByType('navigation')[0], que só está disponível após o carregamento da página. Em ambientes SSR isso pode ter comportamento diferente.
  • Se o servidor não retornar 503 (ex.: retorna 200 mas com uma flag de manutenção no corpo), a detecção automática não funcionará — seria necessário implementar uma lógica adicional via API.
  • O arquivo MaintenanceLayout.vue não precisa de , já que ele não envolve nenhum conteúdo de rota — ele substitui tudo.

🏁 Próximo passo

Agora que você sabe estruturar a interface, veja também:

Criando uma Nova Página: adicionando uma nova página no projeto

Consumo de Dados: como consumir dados via API Pública Persistência de dados: como funciona

Uappi é a melhor opção para o crescimento da sua loja!

;