SeeDropHost

Migrate from Netlify

Checked against the code on 2026-10-30 (version 0.1.0) · Markdown version

SeeDropHost does not run your build command. If your site needs a build, build it as you do today; then point sdh deploy at the repository root (it reads netlify.toml and publishes the publish folder) or straight at the built folder.

What is read automatically

In your projectWhat SeeDropHost does
netlify.toml or seedrop.toml[build] publish: only that folder goes live. [[redirects]] (from, to, status, force, Language/Country conditions, including from = "https://www.example.com/*") and [[headers]] (for + [headers.values]). seedrop.toml wins if both exist. The file itself is never served.
_redirectsread as is: 200/301/302/303/307/308/404/410, * and :splat, :placeholders, ! to force, Language= and Country=, proxy to public addresses. Details
_headersread as is: path blocks with wildcards, Name: value lines (Set-Cookie is dropped)
<form data-netlify="true" name="…">detected on deploy; submissions go to the lead inbox. netlify-honeypot="field" is respected; form-name is added for you. Details
Functions in [functions] directory (default netlify/functions)carried with the deploy and run only if the server has SDH_FUNCTIONS=1 — see below
404.htmlserved with status 404 for unknown paths
Clean URLs/about serves about.html or about/index.html; the other form answers 301 to the one that exists

The same layout is applied to a .zip of the repository root and to a folder dropped in the dashboard.

Functions: opt-in, for a single owner

Supported formats, one file per function (.js, .mjs or .cjs):

// classic
exports.handler = async (event, context) => ({ statusCode: 200, body: "ok" });
// modern
export default async (req) => new Response("ok");

They answer at /.netlify/functions/<name> and /.sdh/functions/<name>, and through 200 rules such as /api/* /.netlify/functions/:splat 200. Limits: 10 seconds, 128 MB of memory, 6 MB request and 6 MB response. process.env holds only the site's variables with the functions scope.

Warning: functions are off by default. Turn them on (SDH_FUNCTIONS=1) only if you own every site on the server. A function runs in a worker of the same process with time and memory limits, but that is not isolation: it can read the database, the files of every site and the server credentials. Whoever publishes a function has full access to the server. With functions off, those paths answer 404.

What is not read yet

  • No build from Git and no deploy on push. [build] command, plugins and [context.*] are not run. Build locally or in CI, then run sdh deploy.
  • Edge functions, scheduled functions and background functions.
  • Functions that require neighbouring files or node_modules (each function is one file), and functions in TypeScript (reported as a warning).
  • In [[redirects]]: query, signed, headers and the Role condition are reported as warnings and ignored. _redirects conditions other than Language and Country never match.
  • Forms: no email notifications, no file uploads, no reCAPTCHA. Spam is filtered by honeypot, link count and rate limit.
  • No global CDN of its own: put Cloudflare in front (self-host guide).

Every one of these shows up in the deploy report, so nothing is skipped silently.

Step by step

  1. Build the site as you do today, for example npm run build.
  2. Create the site and upload it as a draft. A draft gets its own preview address and does not go live; your domain still points to Netlify, so visitors see no change.
npx sdh create my-site
npx sdh deploy ~/my-repo --site my-site --draft
  1. Read the report the command prints: the config file it read, the published folder, functions found, SEO/GEO score, forms found and any rule that was not understood.
  2. Compare the live Netlify site with the draft preview, page by page, including the old addresses listed in your _redirects and netlify.toml:
npx sdh comparar https://www.your-site.com https://<deploy>--my-site.your-server.example --projeto ~/my-repo --json report.json

It blocks (exit code 1) when status, redirects, canonical, noindex, hreflang, forms or a new robots.txt Disallow over existing pages differ, and warns about title, description, h1, JSON-LD, text and URLs missing from the sitemap. A preview address (<deploy>--<site>.) is recognised automatically: the noindex every preview carries does not count, but a noindex your site declares itself still blocks. Use --previa to force this for another address. If the old site's home redirects to another host (bare domain ↔ www), the comparison follows it once and says so.

  1. Fix, deploy again, compare again until nothing blocks. Then publish: npx sdh publish my-site <deploy-id>.
  2. Connect the domain: npx sdh domain:add my-site www.your-site.com. Create the TXT record it prints (proof that the domain is yours) and the CNAME (or A records for the bare domain). Check with npx sdh domain:check www.your-site.com. The domain is served only after the TXT is verified.
  3. Keep the Netlify site until DNS has switched and the leads arrive in the new inbox (npx sdh leads my-site).

Undo

Point DNS back to Netlify. On SeeDropHost every deploy stays available; sdh publish with an earlier id rolls back instantly.