# Migrar do Netlify

Conferido com o código em 2026-10-30 (versão 0.1.0).

O SeeDropHost não roda o seu comando de build. Se o site precisa de build, faça como faz hoje; depois aponte o `sdh deploy` para a raiz do repositório (ele lê o `netlify.toml` e publica a pasta `publish`) ou direto para a pasta pronta.

## O que é lido sozinho

| No seu projeto | O que o SeeDropHost faz |
|---|---|
| `netlify.toml` ou `seedrop.toml` | `[build] publish`: só essa pasta vai para o ar. `[[redirects]]` (from, to, status, force, condições Language/Country, inclusive `from = "https://www.exemplo.com/*"`) e `[[headers]]` (`for` + `[headers.values]`). O `seedrop.toml` vence se os dois existirem. O arquivo nunca é servido. |
| `_redirects` | lido como está: 200/301/302/303/307/308/404/410, `*` e `:splat`, `:marcadores`, `!` para forçar, `Language=` e `Country=`, proxy para endereços públicos. [Detalhes, em inglês](/docs/redirects-headers/) |
| `_headers` | lido como está: blocos por caminho com curingas e linhas `Nome: valor` (o `Set-Cookie` é descartado) |
| `<form data-netlify="true" name="…">` | encontrado no deploy; os envios vão para a caixa de leads. `netlify-honeypot="campo"` é respeitado; o campo `form-name` é colocado para você. [Detalhes, em inglês](/docs/forms/) |
| Funções em `[functions] directory` (padrão `netlify/functions`) | vão junto com o deploy e só rodam se o servidor tiver `SDH_FUNCTIONS=1` — veja abaixo |
| `404.html` | servida com status 404 para endereços que não existem |
| URLs limpas | `/sobre` serve `sobre.html` ou `sobre/index.html`; a outra forma responde 301 para a que existe |

O mesmo vale para um `.zip` da raiz do repositório e para uma pasta solta no painel.

## Funções: desligadas por padrão, para dono único

Formatos aceitos, um arquivo por função (`.js`, `.mjs` ou `.cjs`):

```js
// clássico
exports.handler = async (event, context) => ({ statusCode: 200, body: "ok" });

// moderno
export default async (req) => new Response("ok");
```

Elas respondem em `/.netlify/functions/<nome>` e `/.sdh/functions/<nome>`, e por regras 200 como `/api/*  /.netlify/functions/:splat  200`. Limites: 10 segundos, 128 MB de memória, 6 MB de envio e 6 MB de resposta. O `process.env` tem só as variáveis do site com escopo `functions`.

> **Atenção:** as funções vêm **desligadas**. Ligue (`SDH_FUNCTIONS=1`) só se você for dono de todos os sites do servidor. A função roda num worker do mesmo processo, com limite de tempo e memória, mas isso **não é isolamento**: ela consegue ler o banco, os arquivos de todos os sites e as credenciais do servidor. Quem publica uma função tem acesso total ao servidor. Com as funções desligadas, esses endereços respondem 404.

## O que ainda não é lido

- Não há build a partir do Git nem deploy a cada push. `[build] command`, plugins e `[context.*]` não rodam. Faça o build no seu computador ou na CI e rode `sdh deploy`.
- Edge functions, funções agendadas e funções em segundo plano.
- Funções que fazem `require` de arquivos vizinhos ou de `node_modules` (cada função é um arquivo só) e funções em TypeScript (aparecem como aviso).
- Em `[[redirects]]`: `query`, `signed`, `headers` e a condição `Role` aparecem como aviso e são ignorados. Condições do `_redirects` além de `Language` e `Country` nunca casam.
- Formulários: sem aviso por e-mail, sem envio de arquivo, sem reCAPTCHA. O spam é barrado por honeypot, contagem de links e limite por IP.
- Não há CDN global própria: coloque a Cloudflare na frente ([guia de VPS, em inglês](/docs/self-host/)).

Tudo isso aparece no relatório do deploy; nada é pulado em silêncio.

## Passo a passo

1. Faça o build como hoje, por exemplo `npm run build`.
2. Crie o site e envie como **rascunho**. O rascunho ganha um endereço de prévia próprio e não vai para o ar; o seu domínio continua apontando para o Netlify, então o visitante não vê nada mudar.

```bash
npx sdh create meu-site
npx sdh deploy ~/meu-repo --site meu-site --draft
```

3. Leia o relatório que o comando mostra: o arquivo de configuração lido, a pasta publicada, as funções encontradas, a nota de SEO/GEO, os formulários e qualquer regra que não foi entendida.
4. Compare o site no Netlify com a prévia do rascunho, página por página, inclusive os endereços antigos do seu `_redirects` e do `netlify.toml`:

```bash
npx sdh comparar https://www.seu-site.com.br https://<deploy>--meu-site.seu-servidor.exemplo --projeto ~/meu-repo --json relatorio.json
```

Ele bloqueia (código de saída 1) quando mudam status, redirecionamentos, canonical, noindex, hreflang, formulários ou quando um novo `Disallow` do `robots.txt` cobre páginas que existem, e avisa sobre título, descrição, h1, JSON-LD, texto e endereços que saíram do sitemap. Endereço de prévia (`<deploy>--<site>.`) é reconhecido sozinho: o `noindex` que toda prévia tem não conta, mas o `noindex` que o próprio site declara continua bloqueando. Use `--previa` para forçar isso em outro endereço. Se a página inicial do site antigo redireciona para outro host (domínio sem `www` ↔ `www`), a comparação segue uma vez e avisa.

5. Corrija, envie de novo e compare de novo até nada bloquear. Depois publique: `npx sdh publish meu-site <id-do-deploy>`.
6. Ligue o domínio: `npx sdh domain:add meu-site www.seu-site.com.br`. Crie o registro TXT que ele mostra (a prova de que o domínio é seu) e o CNAME (ou registros A, para o domínio sem `www`). Confira com `npx sdh domain:check www.seu-site.com.br`. O domínio só é servido depois que o TXT é verificado.
7. Mantenha o site no Netlify até o DNS virar e os leads chegarem na caixa nova (`npx sdh leads meu-site`).

## Desfazer

Aponte o DNS de volta para o Netlify. No SeeDropHost todo deploy continua guardado; `sdh publish` com um id anterior volta a versão na hora.
