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
- O layout não é ativado por rota — ele é ativado pelo status HTTP
503na 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.: retorna200mas 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.vuenão precisa de, já que ele não envolve nenhum conteúdo de rota — ele substitui tudo.
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>23<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>78 <!-- Logo da loja -->9 <svg ...></svg>10 </div>11</template>1213<style scoped>14.maintenance-layout {15 display: flex;16 justify-content: center;17 align-items: center;18 flex-direction: column;19 gap: 8px;2021 width: 100%;22 height: 100vh;2324 text-align: center;25}2627/<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}3839/<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}5152@keyframes write-title {53 from { width: 0; border-right-color: #000; }54 to { width: 38ch; border-right-color: transparent; }55}5657@keyframes write-text {58 from { width: 0; border-right-color: #000; }59 to { width: 57ch; border-right-color: #000; }60}6162@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ção34const app = createApp(App);56app.component('DefaultLayout', DefaultLayout);7app.component('MaintenanceLayout', MaintenanceLayout); // Layout de manutenção3. 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;56 if (navigationResources?.responseStatus === 503) return 'MaintenanceLayout'; // 👈78 if (currentRoute.value.meta.layout) {9 return currentRoute.value.meta.layout;10 }1112 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:
| Elemento | Propriedade | Como calcular |
|---|---|---|
| h1 | width: Xch | Use o mesmo N (ou ligeiramente maior para folga) |
| p | steps(N) | Conte os caracteres do texto (incluindo espaços) |
| p | width: Xch | Use o mesmo N (ou ligeiramente maior para folga) |
| p | animation-delay | Deve ser igual à duração da animação do h1 |
"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
🏁 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