Publishing

Publishing takes a directory and puts it on the web at a domain:

surge <path> <domain>
$ surge ./dist lucid-example.surge.sh

   Running as you@example.com (Free)

        project: ./dist
         domain: lucid-example.surge.sh
           size: 3 files, 672 bytes
         upload: [=========================] 100%
            CDN: [=========================] 100%
     encryption: [=========================] 100%

  ┌──────────┬────────────────────────────────────────────────────────────────┬───────────────────────┐
     CERT      *.surge.sh, surge.sh                                            auto-renew          
  ├──────────┼────────────────────────────────────────────────────────────────┼───────────────────────┤
     DNS       using Surge Name Servers                                        geo-aware           
  └──────────┴────────────────────────────────────────────────────────────────┴───────────────────────┘
  ┌──────────┬──────────────────┬───────────────────────┬─────────────────────┬─────────────┬─────────┐
     HTTP      sfo.surge.sh      US, San Francisco      138.197.235.123      D.Ocean          
     HTTP      lhr.surge.sh      GB, London             46.101.67.123        D.Ocean          
     HTTP      yyz.surge.sh      CA, Toronto            159.203.50.177       D.Ocean          
     HTTP      jfk.surge.sh      US, New York           159.203.159.100      D.Ocean          
     HTTP      ams.surge.sh      NL, Amsterdam          188.166.132.94       D.Ocean          
     HTTP      fra.surge.sh      DE, Frankfurt          138.68.112.220       D.Ocean          
     HTTP      sgp.surge.sh      SG, Singapore          139.59.195.30        D.Ocean          
     HTTP      blr.surge.sh      IN, Bangalore          139.59.50.135        D.Ocean          
     HTTP      syd.surge.sh      AU, Sydney             45.76.126.95         Vultr            
     HTTP      nrt.surge.sh      JP, Tokyo              172.104.96.133       Linode           
  └──────────┴──────────────────┴───────────────────────┴─────────────────────┴─────────────┴─────────┘
   Live preview ................................................. 1785787164375-lucid-example.surge.sh
   Production ................................................................. lucid-example.surge.sh

   Success! - Published to lucid-example.surge.sh

   domain written to dist/CNAME

Every publish reports the whole picture: the certificate covering the domain, how DNS is answered, and each edge node of the CDN confirming what it serves—plus the revision's permanent preview URL alongside production.

Some useful forms:

surge ./dist example.com       # publish ./dist to example.com — no prompts
surge . example.com            # publish the current directory
surge ./dist _                 # publish to a fresh generated .surge.sh domain
surge ./dist publish           # publish using the project's CNAME file
surge publish                  # same, from inside the project directory
surge -p ./dist -d example.com # flag form, for pipelines

surge <path> publish is the constructor: run against a directory that has never been published, it prompts for the domain—suggesting a generated .surge.sh subdomain you can accept, replace with any domain you own, or refresh by typing _. Once the project knows its domain (see the CNAME file), the same command publishes with no questions at all.

Choosing a domain

You can publish to two kinds of domain:

  • A surge.sh subdomain — free, instant, no setup: anything-you-like.surge.sh, as long as it's not taken.
  • Your own domain — also free; point it at Surge first. See Domains & DNS.

Prefixing the domain with a protocol controls HTTPS behavior: publish to https://example.com and the platform will redirect all HTTP traffic to HTTPS. See SSL Certificates.

The CNAME file

A project remembers its domain in a file named CNAME at the root of the directory you publish—and Surge writes it for you. That's the domain written to dist/CNAME line in the output above: publish to a domain once, and the project knows where it lives. From then on surge publish goes straight there with no prompt—and every other command resolves its target the same way, so surge rollback or surge dns list inside the project just work.

The convention is shared with GitHub Pages, so a project can move between the two without changes. One thing to know if a build tool generates the directory you publish: the next build may wipe the file with everything else—the framework guides show where to keep it so it survives.

Ignoring files

By default, Surge excludes things that don't belong on a web server:

.git  .*  *.*~  node_modules  bower_components

To exclude more, add a .surgeignore file to your project root. It uses the same syntax as .gitignore:

# .surgeignore
src/
*.map
drafts/

Everything else in the directory is published. Before uploading, the CLI prints a size: line with the file count and total size, so you'll notice if something unexpected is being included. Projects are limited to 10,100 files and 450 MB.

Messages

Attach a message to a publish the way you would to a git commit. Messages show up in the revision list, which makes surge <domain> revs read like a log of everything you've shipped:

surge publish -m "fix nav on mobile"

Managing collaborators while publishing

Add or remove collaborators as part of a publish:

surge publish --add jacob@example.com     # invite jacob as you publish
surge publish --remove jacob@example.com  # revoke as you publish

What happens on publish

A publish is done when it says it's done—everywhere. Your files upload once, then propagate to every edge node of Surge's CDN while the command runs; the CDN: bar is that propagation happening, and the table underneath is each node individually confirming what it now serves. There's no "allow a few minutes for changes to appear," no cache to wait out: when Success! prints, the new revision is live in every region at once.

The cutover is atomic. Every publish creates a new revision, and production points at it only after the upload completes—a failed or interrupted publish leaves the live project exactly as it was. To upload without moving production at all, use a preview.

The output also reports the state of the domain itself—the certificate covering it, how DNS is answered, and the exact records to add if the domain isn't pointing at Surge yet.