Deploying a frontend project with surge.sh

Surge.sh is an amazing service that will deploy your front-end sites for free. And it's extremely easy to use.

If you're deploying a React app, this tutorial assumes you've created it using the create-react-app package.

Let's start! This'll be easy.


1. Install surge

If you haven't used Surge before, from anywhere in Terminal, run:

npm install --global surge

Good job. You must be tired from all this hard work. Feel free to take a break before moving on.


2. Create a CNAME file

Strictly speaking, this step isn't required. If you just want to get something up immediately, skip to step 3 for React apps or step 4 for basic static sites. This step makes it so you don't have to type in your desired domain every single time you re-deploy.

In your React app's public folder (or in your static site's root folder if it isn't a React app), create a new file called CNAME (no file extension). Inside that file, type the name of the domain you'd like to use on surge. It will need to have surge.sh as the top-level domain, and the name you choose should be unique across all of surge. If you're not sure if it's already taken, try going to that page first to see if anyone else has already deployed to that subdomain.

For example, say I want bombdotcom.surge.sh (that's a confusing name to tell people, so I wouldn't recommend using that one). If I see a page saying "project not found", then you're good to use that one!

So in my CNAME file, I would type:

bombdotcom.surge.sh

On to the next step!


3. Add a deploy script to package.json

If you're deploying a regular static site that doesn't require compiling your project into a build folder first, you can skip this step and head to step #4

In package.json you should see a section called scripts. If you used create-react-app to create your app, it probably looks something like this:

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
},

Add another entry script for deploy as such:

"deploy": "npm run build && mv build/index.html build/200.html && surge build"

So now your whole scripts section should look something like this:

"scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "deploy": "npm run build && mv build/index.html build/200.html && surge build"
},

Note: make sure to get your commas right! Don't add a comma on the last item in the object, and don't miss any after any entries before the last one. If you need to, copy/paste your whole package.json file into JSONLint just to make sure it's valid JSON.

This deploy script does a few things.

  1. It runs the build command, which compiles your whole app into a build folder with all your javascript, html, css, etc. compiled into one place. This build folder is the bundled-up folder with your whole site. The code is too ugly to edit manually, but it's a great packaged-up version of your site for deploying. (Whenever you make changes and need to deploy again, you'll need to run a new build)
  2. It changes the name of index.html to 200.html. This feels weird, but it's important if you're using something like React Router in your app. React Router adds routes to the end of your website (E.g. bombdotcom.surge.sh/profile). However, if you try refreshing your page, it will think your website is making an HTTP request to a /profile endpoint, which is not what's really happening. When it receives a 200 response from the server, it will load up your new 200.html page, which allows your app to route the user to the correct page. It's a little confusing - if you want to learn more about this, check out this Medium article
  3. It runs the surge command specifying the build folder as the folder to deploy.

Whew! That was the toughest part. It's all downhill from here!


4. Deploy!

React apps:

In Terminal from your project's root folder, run:

npm run deploy

Static sites

In Terminal, from your project root folder, run:

surge

Answer the questions it asks, which are usually just verifying you're deploying from the right folder. If you cded into the right folder in Terminal before running surge you can likely just hit return.


The very first time you do this, it'll ask you to log in or create an account. Put in an email and password (the password won't look like it's typing, but it really is). You shouldn't have to do that again anytime soon.

It should take over from there! Assuming your project was working locally just fine, Surge will push up your code and launch it on the site you specified in the CNAME file!

If you have purchased a domain you'd like to deploy your code to via surge, check out the Surge tutorial on adding a custom domain.

One last thing - if you have a PDF attachment somewhere in your codebase (like a resume, e.g.), Surge will require you to link a credit card to your account. They won't charge you anything, but it's their way of resolving DMCA issues relating to someone posting copyrighted PDFs.

To link a card to your account, simply type surge card in the terminal to start the process.

Enjoy your deployed site!