Manual de Personalização do Website
v1.0  ·  2024  ·  Ecommerce Estático
Para exportar como PDF:
Abre o browser → prime Ctrl+P (ou Cmd+P no Mac) → selecciona Guardar como PDF como impressora → desactiva os Cabeçalhos e rodapés nas opções → clica Guardar.

Recomendado: Google Chrome ou Microsoft Edge para melhor fidelidade de impressão.
Projecto: VOLT & LEATHER · Stack: Bootstrap 5.3 · Font Awesome 6 · Stripe.js v3 · HTML/CSS/JS puro
Índice
Conteúdo do Manual
  1. 1 Estrutura de Ficheiros
  2. 2 Cores e Tipografia
  3. 3 Produtos — Nome, Preço, Imagens, Tamanhos
  4. 4 Conteúdo — Homepage, Sobre, Contacto, Rodapé
  5. 5 Carrinho e Checkout
  6. 6 Stripe — Integração de Pagamentos
  7. 7 Deploy — Colocar o Site Online
  8. 8 SEO e Analytics
  9. 9 Manutenção e Checklist de Lançamento
Secção 1
Estrutura de Ficheiros

O projecto é um site estático puro — sem servidor, sem base de dados, sem framework. Todos os ficheiros estão numa única pasta que pode ser aberta directamente no browser ou publicada num serviço de hosting estático.

ecommerce-template/

├── index.html → Homepage (hero + colecção + value props + newsletter)
├── sobre.html → Página Sobre (manifesto + timeline + processo + materiais)
├── contacto.html → Página Contacto (formulário + info cards + redes sociais)
├── checkout.html → Checkout multi-step + Stripe + resumo de encomenda

├── the-outlaw.html → Produto No.01 · The Outlaw · €485
├── the-desperado.html → Produto No.02 · The Desperado · €520
├── the-maverick.html → Produto No.03 · The Maverick · €495
├── the-ranger.html → Produto No.04 · The Ranger · €510
├── the-renegade.html → Produto No.05 · The Renegade · €475
├── the-vaquero.html → Produto No.06 · The Vaquero · €545

└── assets/
    ├── css/
    │ └── style.css → Design system completo (variáveis, componentes, layout)
    └── js/
        └── main.js → Carrinho (localStorage) + navbar + animações + size selector

O que faz cada ficheiro

Ficheiro Responsabilidade Dependências externas
index.html Página principal. Contém a navbar, o cart offcanvas, o hero, a grelha de produtos, as value propositions e a newsletter. Bootstrap 5.3, Font Awesome 6, Google Fonts, style.css, main.js
the-*.html Cada ficheiro de produto tem: galeria de imagens, seletor de tamanhos, botão add-to-cart, accordion com detalhes, e secção de produtos relacionados. Idem + Bootstrap accordion JS
checkout.html Fluxo de 3 passos: contacto/morada → método de envio → pagamento. Lê o carrinho do localStorage. Integra Stripe.js para tokenização do cartão. Idem + Stripe.js v3 de js.stripe.com
assets/css/style.css Define as variáveis CSS (:root), reset, tipografia, navbar, botões, cards de produto, carrinho offcanvas, footer e animações.
assets/js/main.js Módulo IIFE auto-contido. Gere o estado do carrinho em localStorage, o badge de contagem, o render do offcanvas, os botões de tamanho, as animações de scroll e a navegação por produto. Bootstrap JS (para o offcanvas)
Nota sobre o ficheiro product.html: Existe também um ficheiro product.html na raiz que serve como template de referência para criar novos produtos. A estrutura é idêntica à dos outros ficheiros de produto.
Secção 2
Cores e Tipografia

Variáveis de cor — onde estão e como mudar

Todas as cores estão definidas como variáveis CSS no bloco :root no início de assets/css/style.css (linha 7). Para mudar uma cor em todo o site basta alterar a variável — não é necessário procurar instâncias individuais.

Variável Valor actual Amostra Onde é usada
--black #000000 Fundo do body, fundo de botões sólidos, fundo do hero
--dark #1a1a1a Sidebar do checkout, campos de formulário, cards de produtos relacionados
--off-white #f4f4f4 Cor principal do texto, bordas de botões ghost, fundos de botões sólidos
--gray #888888 Texto secundário, metadados de produto, descrições no rodapé
--accent #c8a96e Cor dourada: eyebrows, divisores, bordas de hover, preços activos, links

Como editar as cores

Abre assets/css/style.css e localiza o bloco inicial:

:root {
  --black:      #000000;
  --dark:       #1a1a1a;
  --dark-soft:  #111111;
  --off-white:  #f4f4f4;
  --gray:       #888888;
  --gray-light: #555555;
  --accent:     #c8a96e;  /* ← muda esta linha para alterar o dourado */
  --border:     rgba(244, 244, 244, 0.08);
}

Exemplo: para um tema com destaque em cor-de-rosa quente substitui --accent: #c8a96e por --accent: #e84393. A alteração propaga-se automaticamente a todo o site.

A variável --border usa rgba propositadamente — é uma borda semi-transparente pensada para sobrepor fundos escuros. Se mudares o fundo para claro podes ter de a ajustar para algo como rgba(0,0,0,0.12).

Tipografia — as duas fontes do projecto

Variável CSS Fonte Usada em
--serif Playfair Display (Google Fonts) + Georgia, serif Títulos (h1h5), preços, nome da marca, citações
--sans Inter (Google Fonts) + system-ui, sans-serif Corpo, labels, botões, metadados, eyebrows

Como substituir as fontes

Passo 1 — URL do Google Fonts. Em cada ficheiro HTML, no <head>, há uma linha semelhante a esta. Substitui a família pretendida:

<!-- Antes -->
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;0,900;1,400&family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet" />

<!-- Depois (exemplo com EB Garamond + DM Sans) -->
<link href="https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400;0,700;1,400&family=DM+Sans:wght@300;400;500&display=swap" rel="stylesheet" />

Passo 2 — Variáveis CSS em style.css. Actualiza os nomes no bloco :root:

--serif: 'EB Garamond', Georgia, serif;
--sans:  'DM Sans', system-ui, sans-serif;
Para o site funcionar offline sem depender do Google Fonts, descarrega os ficheiros .woff2 em fonts.google.com e coloca-os em assets/fonts/. Depois usa @font-face no início do style.css em vez do link externo.
Secção 3
Produtos

Como mudar nome, preço e descrição num produto

Abre o ficheiro do produto pretendido (ex: the-outlaw.html). Os campos editáveis estão na coluna da direita, dentro de <div class="info-col-sticky">:

<!-- Número do modelo -->
<div class="pdp-model-number">No. 01 · The Essential Six</div>

<!-- Nome do produto -->
<h1 class="pdp-title">The Outlaw</h1>

<!-- Preço (alterar aqui E no main.js — ver abaixo) -->
<div class="pdp-price">€485<small>IVA incluído</small></div>

<!-- Descrição curta -->
<p style="font-size:13px;color:var(--gray);line-height:1.9;margin-bottom:0;">
  A bota que iniciou tudo. Linhas limpas, biqueira apontada, cano alto.
  Full-Grain Italiano curtido em Toscana.
</p>

Como adicionar ou remover tamanhos disponíveis

Os tamanhos são botões dentro de <div class="size-grid">. Adiciona ou remove linhas conforme necessário. A classe unavailable marca um tamanho como esgotado (aparece riscado e não clicável):

<div class="size-grid">
  <!-- Esgotado: adiciona classe "unavailable" -->
  <button class="size-btn unavailable" data-size="38">38</button>

  <!-- Disponível -->
  <button class="size-btn" data-size="39">39</button>
  <button class="size-btn" data-size="40">40</button>

  <!-- Activo por defeito: adiciona classe "active" -->
  <button class="size-btn active" data-size="41">41</button>
  <button class="size-btn" data-size="42">42</button>
  <button class="size-btn" data-size="43">43</button>
</div>

<!-- Input hidden: actualizar o value para o tamanho activo por defeito -->
<input type="hidden" data-size-value data-size-selector="the-outlaw" value="41" />
O atributo data-size-selector no <input hidden> deve coincidir exactamente com o data-add-to-cart do botão. Por exemplo, para The Outlaw ambos têm o valor the-outlaw.

Como substituir imagens (sistema picsum.photos)

Actualmente as imagens são geradas automaticamente por picsum.photos — um serviço que entrega fotografias aleatórias com base numa "seed" (semente). É ideal para protótipos mas deve ser substituído por fotografias reais antes de lançar.

Como funciona a URL actual:

https://picsum.photos/seed/outlaw9A/900/1200?grayscale

↑ seed "outlaw9A" → sempre a mesma foto para este produto
↑ 900/1200 → largura/altura em píxeis
↑ ?grayscale → converte para preto e branco

Como substituir por imagens reais:

  1. Coloca as fotografias na pasta assets/img/ (cria a pasta se não existir). Sugestão de estrutura: assets/img/the-outlaw/main.jpg, assets/img/the-outlaw/detail.jpg, etc.
  2. No HTML do produto, substitui o src de cada <img>:
<!-- Antes -->
<img src="https://picsum.photos/seed/outlaw9A/900/1200?grayscale"
     alt="The Outlaw — Vista Principal"
     class="gallery-main" />

<!-- Depois -->
<img src="assets/img/the-outlaw/main.jpg"
     alt="The Outlaw — Vista Principal"
     class="gallery-main" />

Recomendações para fotografias de produto: proporção 3:4 para a imagem principal (900×1200px), 1:1 para as miniaturas (300×300px). Formato .jpg com compressão ~80% para equilíbrio entre qualidade e velocidade.

Como actualizar o preço no main.js

O preço em main.js é o que é usado para calcular o total do carrinho. É independente do que está escrito no HTML — é aqui que o carrinho lê o valor real. Localiza o objecto MODELS no início do módulo Cart:

// assets/js/main.js — linha 29
const MODELS = {
  'the-outlaw':     { name: 'The Outlaw',     price: 485 },
  'the-desperado':  { name: 'The Desperado',  price: 520 },
  'the-maverick':   { name: 'The Maverick',   price: 495 },
  'the-ranger':     { name: 'The Ranger',     price: 510 },
  'the-renegade':   { name: 'The Renegade',   price: 475 },
  'the-vaquero':    { name: 'The Vaquero',    price: 545 },
};
Quando alterares um preço, tens de o alterar em dois sítios: (1) no HTML do produto (.pdp-price) e (2) no MODELS do main.js. Se só alterares num, o preço exibido e o preço cobrado no checkout ficarão dessincronizados.

Como alterar os produtos relacionados

No final de cada ficheiro de produto há uma secção <section id="related"> com uma grelha de 4 cards. Cada card segue este padrão — basta substituir o slug, o nome, o preço e a seed da imagem:

<div class="col-6 col-md-3 product-card-wrap">
  <a href="the-desperado.html" class="d-block text-decoration-none">
    <div class="product-card">
      <img src="https://picsum.photos/seed/desp77A/600/800?grayscale"
           alt="The Desperado" class="product-card-img" />
      <div class="product-card-number">No. 02</div>
      <div class="product-card-overlay">
        <div class="product-card-info">
          <div class="product-card-name">The Desperado</div>
          <div class="product-card-price">€520</div>
        </div>
      </div>
    </div>
    <div class="product-card-label">
      <span class="product-card-label-name">The Desperado</span>
      <span class="product-card-label-price">€520</span>
    </div>
  </a>
</div>
Secção 4
Conteúdo

Homepage (index.html) — mapa de secções

Secção Elemento HTML O que editar
Hero <section id="hero"> Tagline principal (.hero-title), subtítulo (.hero-subtitle), eyebrow (.hero-eyebrow), imagem de fundo (.hero-img-placeholdersrc), stats (.hero-meta-number)
Marquee strip <div class="marquee-strip"> Textos dentro de <template id="marqueeContent"> — cada <span class="marquee-item">
The Essential Six <section id="collection"> Título da secção, descrição. Os cards de produto — ver Secção 3 deste manual.
Value Props <section id="values"> Título (.value-title) e texto (.value-text) de cada um dos 3 cards. Ícone (<i class="fa-solid fa-...">)
Imagem full-width <div style="height:60vh..."> Imagem de fundo, citação e botão CTA no centro
Newsletter / CTA <section id="cta-section"> Título (.cta-title), subtítulo (.cta-subtitle). O formulário não envia email por defeito — ver nota abaixo.
O formulário de newsletter em index.html tem onsubmit="return false;" — não envia email. Para o activar precisas de integrar um serviço externo como Mailchimp, ConvertKit ou Buttondown. Cada um fornece um snippet de formulário HTML para substituir o actual.

Página Sobre (sobre.html) — como editar a timeline

A timeline está em <section id="timeline">. Cada entrada é um bloco .timeline-item:

<div class="timeline-item fade-up">
  <!-- Ano (muda apenas o texto) -->
  <div class="timeline-year">2024</div>
  <div class="timeline-content">
    <!-- Título do evento -->
    <h3>VOLT &amp; LEATHER Nasce</h3>
    <!-- Descrição -->
    <p>Após dois anos de prototipagem, a marca lança os seis modelos...</p>
  </div>
</div>

Para adicionar uma entrada: copia um bloco .timeline-item e cola antes do último </div> da <section id="timeline">. Para remover: apaga o bloco .timeline-item completo.

Processo de fabrico (craft steps)

Em <section id="craft">, cada passo é um .craft-step. O número (.craft-step-number), o título (.craft-step-title) e o texto (.craft-step-text) são todos editáveis livremente.

Página Contacto (contacto.html) — alterar email e morada

As informações de contacto estão nos cards à direita do formulário, cada um num bloco .info-card:

<!-- Email -->
<div class="info-card">
  <div class="info-card-icon"><i class="fa-solid fa-envelope"></i></div>
  <div class="info-card-title">Email</div>
  <!-- ↓ Altera aqui -->
  <div class="info-card-value">hello@voltandleather.com</div>
  <div class="info-card-sub">Resposta em 24 horas úteis</div>
</div>

<!-- Morada -->
<div class="info-card">
  <div class="info-card-icon"><i class="fa-solid fa-location-dot"></i></div>
  <div class="info-card-title">Atelier</div>
  <!-- ↓ Altera aqui -->
  <div class="info-card-value">Alcanena, Portugal</div>
  <div class="info-card-sub">Visitas mediante marcação prévia.</div>
</div>

Rodapé — actualizar links e redes sociais

O rodapé é repetido em todos os ficheiros HTML. As redes sociais estão em .footer-social no final do <footer>:

<div class="footer-social">
  <!-- Substitui os href="#" pelos URLs reais das tuas páginas -->
  <a href="https://instagram.com/voltandleather" aria-label="Instagram" target="_blank">
    <i class="fa-brands fa-instagram"></i>
  </a>
  <a href="https://pinterest.com/voltandleather" aria-label="Pinterest" target="_blank">
    <i class="fa-brands fa-pinterest"></i>
  </a>
  <a href="https://tiktok.com/@voltandleather" aria-label="TikTok" target="_blank">
    <i class="fa-brands fa-tiktok"></i>
  </a>
</div>
O rodapé não é um componente partilhado — está duplicado em cada ficheiro HTML. Sempre que alteres o rodapé (email, links, copyright) tens de fazer a alteração em todos os ficheiros: index.html, sobre.html, contacto.html, the-outlaw.html, etc. Uma forma mais eficiente é usar um editor com busca e substituição global (ex: VS Code: Ctrl+Shift+H).
Secção 5
Carrinho e Checkout

Como funciona o localStorage

O carrinho não precisa de servidor — é guardado localmente no browser do utilizador através da Web Storage API. Os dados persistem entre sessões até o utilizador limpar o histórico do browser.

Detalhe Valor
Chave localStorage vl_cart
Formato Array JSON: [{ slug, size, name, price, qty }, ...]
Onde é escrito assets/js/main.js — função save() linha 44
Onde é lido assets/js/main.js — função load() linha 39; e checkout.html — função loadCart()

Para inspeccionar o conteúdo do carrinho no browser: abre as Ferramentas de Programador (F12) → aba Application (Chrome) ou Storage (Firefox) → Local Storage → selecciona o domínio → procura a chave vl_cart.

Como limpar o carrinho — função clearCart()

A função clearCart() está definida em checkout.html (linha 833) e é chamada automaticamente após um pagamento bem-sucedido. Podes chamá-la manualmente a partir da consola do browser para testar:

// No ficheiro checkout.html
function clearCart() {
  localStorage.removeItem('vl_cart');
}

// Para adicionar um botão "Limpar Carrinho" à interface:
// 1. Adiciona o botão no HTML do offcanvas em qualquer página
<button onclick="localStorage.removeItem('vl_cart'); location.reload();">
  Limpar Carrinho
</button>

Códigos promocionais

Os códigos promo estão num objecto simples em checkout.html (linha 826). A chave é o código (em maiúsculas) e o valor é a percentagem de desconto:

// checkout.html — linha 826
const PROMO_CODES = {
  'VOLT10':     10,  // 10% de desconto
  'LEATHER20':  20,  // 20% de desconto
  // Adiciona mais entradas aqui:
  'LAUNCH30':   30,  // 30% de desconto de lançamento
  'FRIEND15':   15,  // 15% para amigos
};
Os códigos promocionais estão em JavaScript no lado do cliente — o utilizador pode vê-los inspeccionando o código fonte da página. Para segurança real, a validação de códigos promo deve ser feita no servidor (backend). Para um projecto pequeno este nível é aceitável.

Métodos de envio — alterar preços

Os preços de envio estão no objecto SHIPPING_PRICES em checkout.html (linha 837). As chaves correspondem ao valor do input[type=radio] em cada opção de envio no HTML:

// checkout.html — linha 837
const SHIPPING_PRICES = {
  free:          0,   // Standard CTT — grátis
  express_pt:    8,   // Express DHL Portugal — €8
  europe:       15,   // Internacional Europa — €15
  international:30,   // Internacional geral — €30
};

Para adicionar um novo método de envio: adiciona uma entrada ao objecto, e no HTML do Step 2 adiciona uma nova <label class="shipping-option"> com um input[type=radio] cujo value coincida com a nova chave.

Secção 6
Stripe — Integração de Pagamentos

Passo a passo para criar uma conta Stripe

  1. Acede a stripe.com e clica em "Start now" / "Criar conta".
  2. Preenche com o teu email e cria uma password.
  3. Confirma o email através da mensagem enviada.
  4. Preenche o perfil do negócio: tipo de empresa, país (Portugal), categoria do produto (Calçado / Vestuário).
  5. Para aceitar pagamentos reais, completa a verificação KYC (Know Your Customer): dados pessoais, NIF, IBAN da conta bancária para receber os fundos.
  6. Enquanto a verificação não é concluída, podes usar o modo de teste sem limitações.

Onde colocar a Publishable Key

A Publishable Key é pública — é seguro colocá-la no frontend. Não confundir com a Secret Key (que nunca deve estar no frontend). Em checkout.html, linha 822:

/* checkout.html — linha 822 */
/* Obtém a tua chave em: https://dashboard.stripe.com/apikeys */

const STRIPE_PUBLISHABLE_KEY = 'pk_live_51AbCdEfGhIjKlMnOpQrStUvWxYz...';
//                               ↑ Começa sempre com pk_live_ (modo live) ou pk_test_ (modo teste)

Para encontrar a tua chave: Dashboard StripeDevelopersAPI keys → copia a "Publishable key".

O que é o PaymentIntent e porque precisa de backend

O fluxo completo do Stripe tem dois passos:

  1. Frontend (já implementado): O Stripe.js tokeniza os dados do cartão e cria um PaymentMethod — os dados sensíveis nunca passam pelo teu servidor.
  2. Backend (ainda não implementado — TODO no código): O teu servidor usa a Secret Key para criar um PaymentIntent com o valor exacto. O Stripe retorna um clientSecret. O frontend usa esse clientSecret para confirmar o pagamento.
Não é possível criar um PaymentIntent directamente no frontend — a Secret Key nunca deve estar exposta no browser. O checkout actual simula o sucesso sem cobrar nada de real. Para cobrar pagamentos reais é obrigatório um backend.

Opções de backend simples

Opção Custo Dificuldade Quando usar
Netlify Functions Gratuito (125k req/mês) Baixa Site já hospedado no Netlify
Vercel Serverless Gratuito (100GB-h/mês) Baixa Site hospedado no Vercel
Node.js + Express Custo do servidor (Railway, Render — gratuito) Média Controlo total, lógica complexa
Stripe Checkout (hosted) 0% + taxas Stripe standard Muito baixa Preferir a página de checkout do próprio Stripe

Snippet completo — endpoint Node.js/Express

Cria um ficheiro server.js na raiz do projecto e instala as dependências: npm install express stripe cors

// server.js — Endpoint para criar o PaymentIntent
const express = require('express');
const cors    = require('cors');
const stripe  = require('stripe')('sk_live_SUA_SECRET_KEY_AQUI');

const app = express();
app.use(cors());
app.use(express.json());

app.post('/api/create-payment-intent', async (req, res) => {
  const { paymentMethodId, amount, currency, email, items } = req.body;

  // Validação básica
  if (!paymentMethodId || !amount || amount < 50) {
    return res.status(400).json({ error: 'Dados inválidos.' });
  }

  try {
    const paymentIntent = await stripe.paymentIntents.create({
      amount:               amount,    // em cêntimos (ex: 485 euros = 48500)
      currency:             currency || 'eur',
      payment_method:       paymentMethodId,
      receipt_email:        email,
      confirm:              true,
      return_url:           'https://voltandleather.com/checkout.html',
      automatic_payment_methods: {
        enabled:            true,
        allow_redirects:    'never'
      },
      metadata: {
        items: JSON.stringify(items)
      }
    });

    res.json({
      clientSecret: paymentIntent.client_secret,
      status:       paymentIntent.status
    });

  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.listen(3001, () => console.log('Stripe backend a correr na porta 3001'));

Como activar o modo live

  1. No Dashboard Stripe, desactiva o Test mode (toggle no canto superior direito).
  2. Vai a Developers → API keys e copia a Publishable key que começa com pk_live_.
  3. Em checkout.html, substitui o valor de STRIPE_PUBLISHABLE_KEY.
  4. No backend, substitui a Secret Key por sk_live_....
Nunca commits a Secret Key (sk_live_...) para um repositório Git público. Usa variáveis de ambiente: no Netlify/Vercel configura STRIPE_SECRET_KEY nas definições do projecto e acede via process.env.STRIPE_SECRET_KEY.

Cartões de teste Stripe

Número do cartão Resultado CVC / Expiração
4242 4242 4242 4242 Pagamento bem-sucedido Qualquer 3 dígitos / qualquer data futura
4000 0000 0000 0002 Cartão recusado (genérico) Idem
4000 0027 6000 3184 Requer autenticação 3D Secure Idem
4000 0000 0000 9995 Recusado — sem fundos suficientes Idem
Secção 7
Deploy — Colocar o Site Online

Netlify — drag & drop (mais simples)

  1. Cria uma conta gratuita em netlify.com.
  2. Na dashboard, na secção "Sites", encontras uma área com o texto "Drag and drop your site output folder here".
  3. Arrasta a pasta ecommerce-template/ (a pasta raiz do projecto) para essa área.
  4. O Netlify faz o upload e atribui um URL temporário tipo https://random-name-123.netlify.app.
  5. Para actualizar: volta ao site na dashboard → aba "Deploys" → arrasta de novo a pasta actualizada.
Para deploys automáticos sempre que fazes push para o GitHub: em vez do drag & drop, usa "Import an existing project" no Netlify e liga ao repositório Git. Cada commit na branch principal despoleta um deploy automático.

Vercel — via CLI

# Instala o Vercel CLI (só na primeira vez)
npm install -g vercel

# Na pasta do projecto
cd ecommerce-template
vercel deploy

# Responde às perguntas:
# Set up and deploy? Y
# Which scope? (a tua conta)
# Link to existing project? N
# Project name: volt-and-leather (ou o que quiseres)
# In which directory is your code? ./  (a raiz)

# Para deploy em produção (URL fixo):
vercel --prod

GitHub Pages

  1. Cria um repositório no GitHub com o nome volt-and-leather (ou qualquer outro).
  2. Faz upload de todos os ficheiros do projecto para a branch main.
  3. No repositório: SettingsPages → Source: "Deploy from a branch" → Branch: main → Folder: / (root) → Save.
  4. O site fica disponível em https://SEU-USER.github.io/volt-and-leather/.
O GitHub Pages serve apenas ficheiros estáticos — não suporta o backend Node.js/Express necessário para o Stripe em modo live. Para o checkout com pagamentos reais, usa Netlify Functions ou Vercel Serverless Functions (ambos gratuitos no plano base).

Domínio personalizado

Depois de teres o site no ar num dos serviços acima:

  1. Regista um domínio num registrar (ex: Namecheap, GoDaddy, Namebio, SAPO Dominios para .pt).
  2. No painel do Netlify/Vercel: vai a Domain settingsAdd custom domain → introduz o teu domínio.
  3. O serviço dá-te os registos DNS a configurar (normalmente um registo CNAME a apontar para o URL do serviço, ou registos A com IPs específicos).
  4. No painel do teu registrar, em DNS Management, adiciona os registos indicados.
  5. Aguarda a propagação DNS (pode demorar até 48h, geralmente menos de 1h).
  6. O SSL/HTTPS é configurado automaticamente pelo Netlify/Vercel via Let's Encrypt.
Secção 8
SEO e Analytics

Meta tags Open Graph (og:image, og:title)

Adiciona estas meta tags dentro do <head> de cada página. São usadas quando o URL é partilhado no Facebook, Instagram, WhatsApp, etc.:

<!-- Coloca dentro do <head> de cada página -->

<!-- SEO básico -->
<meta name="description" content="VOLT & LEATHER — Botas Cowboy Handmade de Portugal. Apenas 6 modelos exclusivos. Couro Italiano. Craftsmanship Português." />

<!-- Open Graph para redes sociais -->
<meta property="og:type"        content="website" />
<meta property="og:site_name"   content="VOLT & LEATHER" />
<meta property="og:title"       content="VOLT & LEATHER — Handmade Cowboy Boots · Portugal" />
<meta property="og:description"  content="Seis modelos. Couro Italiano. Feitos à mão em Portugal." />
<meta property="og:image"       content="https://voltandleather.com/assets/img/og-cover.jpg" />
<meta property="og:image:width"  content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:url"         content="https://voltandleather.com" />

<!-- Twitter Card -->
<meta name="twitter:card"        content="summary_large_image" />
<meta name="twitter:title"       content="VOLT & LEATHER — Handmade Cowboy Boots" />
<meta name="twitter:description"  content="Seis modelos. Couro Italiano. Feitos à mão em Portugal." />
<meta name="twitter:image"       content="https://voltandleather.com/assets/img/og-cover.jpg" />

A imagem og-cover.jpg deve ter 1200×630px. Usa o Facebook Sharing Debugger (developers.facebook.com/tools/debug) para testar.

Google Analytics 4

Regista-te em analytics.google.com, cria uma propriedade GA4 e obtém o ID de medição (formato G-XXXXXXXXXX). Depois adiciona este snippet no <head> de cada página, antes de fechar a tag:

<!-- Google Analytics 4 — substitui G-XXXXXXXXXX pelo teu ID -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXXXXX');
</script>

Google Search Console — verificação

Em search.google.com/search-console, adiciona o teu domínio. O método mais simples de verificação é a meta tag HTML — adiciona ao <head> da index.html:

<!-- Google Search Console — substitui XXXXXXXXXXXXXXXXXXXX pelo teu token -->
<meta name="google-site-verification" content="XXXXXXXXXXXXXXXXXXXX" />

Sitemap.xml — exemplo completo

Cria um ficheiro sitemap.xml na raiz do projecto. Ajusta o <loc> com o teu domínio real e as datas <lastmod>:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">

  <url>
    <loc>https://voltandleather.com/</loc>
    <lastmod>2024-01-01</lastmod>
    <changefreq>monthly</changefreq>
    <priority>1.0</priority>
  </url>

  <url>
    <loc>https://voltandleather.com/sobre.html</loc>
    <lastmod>2024-01-01</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.7</priority>
  </url>

  <url>
    <loc>https://voltandleather.com/contacto.html</loc>
    <lastmod>2024-01-01</lastmod>
    <changefreq>yearly</changefreq>
    <priority>0.6</priority>
  </url>

  <url>
    <loc>https://voltandleather.com/the-outlaw.html</loc>
    <lastmod>2024-01-01</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.9</priority>
  </url>

  <url>
    <loc>https://voltandleather.com/the-desperado.html</loc>
    <lastmod>2024-01-01</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.9</priority>
  </url>

  <url>
    <loc>https://voltandleather.com/the-maverick.html</loc>
    <lastmod>2024-01-01</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.9</priority>
  </url>

  <url>
    <loc>https://voltandleather.com/the-ranger.html</loc>
    <lastmod>2024-01-01</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.9</priority>
  </url>

  <url>
    <loc>https://voltandleather.com/the-renegade.html</loc>
    <lastmod>2024-01-01</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.9</priority>
  </url>

  <url>
    <loc>https://voltandleather.com/the-vaquero.html</loc>
    <lastmod>2024-01-01</lastmod>
    <changefreq>monthly</changefreq>
    <priority>0.9</priority>
  </url>

</urlset>

Depois de criar o sitemap.xml, submete-o no Google Search Console: Sitemaps → introduce sitemap.xmlSubmit.

Secção 9
Manutenção e Checklist de Lançamento

Como actualizar o Bootstrap

O Bootstrap é carregado via CDN (jsDelivr). Para actualizar para uma nova versão, substitui o número da versão nos links de CSS e JS em todos os ficheiros HTML. Actualmente usa a versão 5.3.2:

<!-- CSS — no <head> -->
<!-- Antes: -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" />

<!-- Depois (exemplo para 5.3.3): -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />

<!-- JS Bundle — antes de fechar </body> -->
<!-- Antes: -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>

<!-- Depois: -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
Antes de actualizar para uma versão major (ex: Bootstrap 6.x), verifica o changelog em getbootstrap.com/docs/versions — versões major podem ter breaking changes que requerem ajustes no HTML e CSS.

Como actualizar o Font Awesome

O Font Awesome é carregado via Cloudflare CDN. Actualmente usa a versão 6.5.0. Substitui nos ficheiros HTML:

<!-- Antes: -->
<link rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" />

<!-- Depois (ex: 6.6.0): -->
<link rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css" />

Verifica a versão mais recente em cdnjs.com/libraries/font-awesome.

Como fazer backup

O projecto é 100% estático — não há base de dados. O backup consiste simplesmente em copiar a pasta:

  1. Backup manual: Copia a pasta ecommerce-template/ para um serviço de cloud storage (Google Drive, Dropbox, OneDrive) ou para um disco externo.
  2. Backup com Git (recomendado): Cria um repositório privado no GitHub/GitLab e faz commit regularmente. Cada commit é um snapshot do estado do site.
  3. Backup automático: Se usas Netlify ou Vercel, cada deploy fica guardado e podes fazer rollback para qualquer versão anterior na dashboard.
# Inicializar repositório Git (só na primeira vez)
git init
git add .
git commit -m "Initial commit — VOLT & LEATHER v1.0"

# Ligar a repositório remoto (GitHub)
git remote add origin https://github.com/SEU-USER/volt-and-leather.git
git push -u origin main

# Guardar alterações futuras
git add .
git commit -m "Actualizar preço The Vaquero para €560"
git push

Checklist de Lançamento

Antes de tornar o site público, verifica todos os itens abaixo:

Usa o Google PageSpeed Insights (pagespeed.web.dev) para medir a performance do site antes do lançamento. O principal ganho fácil é optimizar o tamanho das imagens — usa o formato WebP e comprime abaixo dos 200KB por imagem de produto.

VOLT & LEATHER · Manual de Personalização v1.0 · 2024
Projecto estático — Bootstrap 5.3 · Font Awesome 6 · Stripe.js v3