Migrate from Netlify
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 project | What 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. |
_redirects | read as is: 200/301/302/303/307/308/404/410, * and :splat, :placeholders, ! to force, Language= and Country=, proxy to public addresses. Details |
_headers | read 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.html | served 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 runsdh deploy. - Edge functions, scheduled functions and background functions.
- Functions that
requireneighbouring files ornode_modules(each function is one file), and functions in TypeScript (reported as a warning). - In
[[redirects]]:query,signed,headersand theRolecondition are reported as warnings and ignored._redirectsconditions other thanLanguageandCountrynever 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
- Build the site as you do today, for example
npm run build. - 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
- 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.
- Compare the live Netlify site with the draft preview, page by page, including the old addresses listed in your
_redirectsandnetlify.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.
- Fix, deploy again, compare again until nothing blocks. Then publish:
npx sdh publish my-site <deploy-id>. - 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 withnpx sdh domain:check www.your-site.com. The domain is served only after the TXT is verified. - 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.