How to Make a Professional Personal Website for Free
Tuesday, March 31st, 2020 · 24 min read
Started a little blog just to get some traffic
Old folks’ll tell you not to play in traffic, uh
A million hits and the web crashes, damn
— Kanye West, “Made in America” (2011)
At the same time — as it has been for the past five decades — compute power has become cheaper than ever.
One byproduct of this progression is that it’s made launching a new website exceedingly easy, and pretty much free:
When I first got started with web development, I had to buy web hosting through GoDaddy or Namecheap (about $72/year). I’d wait half an hour or so for my account to be created on their server, and in the meantime I’d write HTML code by hand. Then, I’d have to use the terminal to upload the HTML directly to the server.
Now, I can download a free HTML5 template, drag and drop my site files onto a web UI, and instantly get a globally available, scalable site for $0/year. And it’s just $12 more if I want my own domain (like natecation.com).
That is: there’s never been an easier, cheaper, better time to claim one’s own little corner of the internet.
Here’s how you can get started.
This tutorial takes about an hour if you follow the instructions from start to finish, and as much as two if you use a different template or want to play around with the layout or styling. This doesn’t need to be finished in one sitting, but if you’d like to, make sure to allot enough time to do so.
Whether you speak English, Spanish, Chinese, or Esperanto, HTML is the one true language of the internet.
Right-click on this page, hit “Inspect” (it might also be “Inspect Element,” depending on your browser, and on Safari you’ll have to enable the Develop Menu) and you’ll see the soup of
> that the ‘net is made out of.
Every website you visit is some permutation of those characters, which means for your personal website you’ll need some HTML code of your own.
Already have HTML code you want to upload? Skip to “Upload to the Internet”
Fortunately, you don’t even need to know HTML: there exist many awesome, free templates that are highly customizable even for beginners. One of my favorite sources for these templates is HTML5 UP.
If you have zero prior experience, I recommend downloading “Aerial” (about halfway down the page) — it’s a super-simple, one-page template perfect for a personal website.
If you already know a bit of HTML, though, feel free to take a look at some of the other templates available, too.
The next two parts of this tutorial give a quick beginner’s overview of HTML and CSS, two languages which are used to create website layouts and style them. I reference very specific parts of the Aerial template code (like line numbers), so if you’re just starting out and want to follow along as closely as possible, download Aerial.
Regardless, once you’ve made your choice, click “Free Download”. You should see a .zip file pop up in your downloads. This file contains all of the template code, but compressed to save bandwidth and make the download faster.
To use the template, you’ll need to unzip it: double-click the downloaded file (you might also have to click “Extract”).
Once the files are unzipped, you’re ready to start digging into the HTML.
First, I recommend moving the template folder out of your Downloads and into your Documents or Desktop, so you don’t accidentally delete your work when if you ever clean out your Downloads.
index.html file to open it in your default web browser.
You should see the template filled in with some placeholder content about a guy named Adam Jensen — keep this browser window open.
If you don’t see Notepad or TextEdit in the “Open With” window, you need to open Notepad or TextEdit through the start menu (Ctrl + Windows) or spotlight (Command + Space), and then open the
index.html file by clicking “File” then “Open” (Ctrl + O).
On macOS, you might not see code immediately (it should be black and white text), but instead some color and different font sizes instead (i.e. formatted text).
If so, you’ll need to change your TextEdit preferences.
Check the “Display HTML files as HTML code instead of formatted text” option.
Next, close the Preferences window and quit TextEdit. Then, repeat the steps above (right click on
index.html, hover over the “Open With” option, click “TextEdit”).
You should see HTML code: this turns into the blue and white website about “Adam Jensen” you saw earlier in your browser.
Let’s get coding! First, change the text in between
Aerial by HTML5 UP) to your name.
Next, do the same with the text between the
<h1> and the
Then, hit save (Ctrl + S) and go back to the browser window you opened earlier with the HTML file. Refresh the page, and you should see your changes!
The text you changed between the
</title> now shows up in the tab title (in the image above, look in the upper left — if you have a lot of tabs open and the titles are hidden, maybe open a new window).
The text you changed between the
</h1> now shows up as the big white text in the center of the page (
h1 stands for “heading 1”, and it’s the biggest heading available in HTML — it goes all the way down to heading 6, or
One thing you might notice about the code we’re editing is that it’s really difficult to see what’s going on in the black and white expanse.
If you right click anywhere on the rendered blue and white page in the browser with our HTML file and hit “Inspect” again, you’ll see that our browser helpfully highlights our source code — in the image below, actual text that is shown on-screen is black, and the
/ which aren’t shown on screen are purple (comments, which are never shown and are just notes to yourself so you know what you were thinking when you were writing the code, are green).
The colors might be a little different if you’re using a different browser or are in dark mode (where, for instance, the text shown on-screen might be white instead of black), but the idea is the same.
This is called syntax highlighting, and it helps prevent mistakes — when you see a new color in a place you don’t expect, you’ll know to stop and think before typing more.
There are a few tools (called “editors”) that offer syntax highlighting (among many other features that make it easier to write code), and you may have heard of a few — Notepad++, Atom, and VSCode are some big names. I’ve used all three, beginning with Notepad++, and I currently use VSCode.
They’re all broadly similar, but for the purposes of following along, I suggest you download VSCode at https://code.visualstudio.com/.
Once it’s downloaded, unzip it and install it (on Mac, you’ll need to move it to your “Applications” folder). Then, open the editor.
You’ll see the VSCode “Welcome” screen.
Click “Open Folder” in the top left, and then select the folder (not the
index.html file itself) containing your HTML (it’s probably called
html5up-aerial, in your
Desktop if you moved it).
Once the folder is opened, you’ll see the list of files in it in the left sidebar. Click
Now, our code is all pretty and highlighted! Editing it should be much clearer: for now, you generally only want to change the white text in between the
<. That’ll directly change the text displayed on screen.
At the very least, let’s get the content of the site minimally changed so it’s fully customized (we’ll remove all the “Adam Jensen” stuff) so you can upload the site and send it to your friends.
We still need to change the subtitle (“Security Chief • Cyborg • Never asked for this”), the social links, and the copyright at the bottom.
First, let’s change the subtitle. You’ve probably already found it — it’s the text between
</p> right under the
</h1> where you added your name earlier (the
Security Chief • Cyborg • Never asked for this text — the
creates a special type of space, and
• creates a bullet point; even though they are a different color than the normal text in the editor, they are safe to delete along with the rest of the text). The
p stands for paragraph, and it’s generally used for displaying blocks of text.
Change the subtitle to something that suits you — if you have a LinkedIn profile, that’d be a good place to put your headline.
After changing it, save the file (Ctrl + S) and then refresh the window again. You should see the new subtitle immediately.
Next up, you’ll want to change the social links.
Another important feature of an editor like VSCode is the line numbering (so we can now talk precisely about the location of our edits in the HTML code) — you’ll be able to find the social link code between lines 27 and 31:
To change where the links go, you’ll need to change the green text right after
href (keep the quotations). If you don’t have a certain social account (for instance, if you don’t have a Dribbble), just delete the line.
You can think of
href as meaning “to” — it specifies where the link is going. It’s short for “hypertext reference” — “hypertext” is “text which contains links to other texts” and a “hypertext reference” is a “reference” (i.e. a link) to another page of “hypertext.”
Taking another step back, HTML stands for “hypertext markup language” (it’s a way of telling the browser how hypertext should be “marked up,” or displayed). You are writing hypertext!
Make sure to include
https in each link to another website, and if you want to link to an email address, prepend it with
mailto as in
mailto:email@example.com. After changing the
href of each link, save, go back to your browser, and refresh.
If you hover over you each link and (on Chrome, at least) look at the lower left-hand corner, you should see that all the links are updated.
You might be curious about why there’s text in each social link that’s not shown — for instance,
<span class="label"> and
<li> <a href="https://twitter.com/your_twitter_username" class="icon brands fa-twitter" > <span class="label">Twitter</span> </a> </li>
The text is hidden, but it’s there for accessibility purposes — if a visually impaired user is using a screenreader to browse your site (and hence won’t be able to see the Twitter logo), the screenreader will be able to read “Twitter” aloud so the user knows where the link goes.
How is the link hidden? The answer is CSS.
On the left-hand side of VSCode, if you click
main.css, you’ll see the stylesheets associated with the template — these files define the styles (colors, font sizes, etc.) applied to your HTML.
Press Ctrl + F (this lets you do an arbitrary text search across an entire file), and search for
display: none in line 146 tells the browser not to show the “Twitter” label we saw above — that’s why even though the text is white in the editor, we don’t see it in the resulting page.
While we’re in
main.css, scroll to line 214. Here, you can see all the styles applied to the background of the page. On line 229, you can change the background color of the whole page.
In your browser, go to Google and search for “hex color picker.” You should see a color picker pop up that you can choose a new color from.
Pick your favorite color, and then copy the hex code (it’s in the top box, right under the palette, containing the hashtag followed by 6 letters and numbers) and replace the background on line 229 (the entire part between the colon and the semicolon — the final result should not contain
Save, and then go back to the HTML file in your browser and refresh.
Now, all that’s left for a minimum viable website is to update the copyright footer at the bottom with your name (to be fair, a minimum viable website could just be a blank page, but we’re going for something presentable).
Before you go ahead and edit the HTML to do so, please read this next section.
If you remember what HTML5 UP’s website looked like, you’ll notice that in the top right it says the templates are “100% Free” — “under the Creative Commons.” That last bit is important.
These templates are free as long as you adhere to the terms of the Creative Commons License.
That is, you can use the template however you like as long as you keep HTML5 UP’s credit in the copyright footer.
So, change the footer on line 37 to your name, making sure to leave the HTML5UP branding reading “Design: HTML5UP”:
Licenses like the Creative Commons are common in the world of free and open-source software (which this template is a part of), and there are quite a few that you might see in the wild, such as the MIT license — where you can do pretty much whatever you want (including keep your code secret) as long as long as you include a copy of the license in your source code; and the GPL license — where any changes you make to the code have to also be made open source (i.e. public).
Some people complain, but it’s completely reasonable — this software is given out for free, and is often the result of hours and hours of work. The least we can do is respect its creators’ wishes — open source is often thankless work.
Even better, as you get better at HTML, maybe you’ll be able to design your own templates and give back to the community yourself.
But in the meantime, you’ve got a website that’s ready to be put online:
Also — this has just a been basic intro to HTML, but if you want to learn more, there are a bunch of great free online resources I recommend: Codecademy, FreeCodeCamp, w3schools (yes, even w3schools), and straight Google (“how to change the font on a website”) to name a few. These resources can teach you how to add animations, change text formatting, create complex gradients, and more.
For now, though, let’s put this site on the internet.
Sign up with your email.
After confirming your email, you should see a screen similar to this one:
Now, drag and drop your site folder onto the dotted rectangle, and Netlify will automatically upload your site. You’ll see something like this, except with less info:
Netlify will first upload your website to their main server, and then they will distribute it all over the world to their other servers in Europe, Asia, SF, NYC, and various other locations. When a visitor navigates to your site, they’ll be automatically sent to the closest available server. Netlify also has the resources to handle millions of visitors if your site becomes super popular, and they’ll encrypt traffic to your website with HTTPS.
Before Netlify, you’d have to buy a Linux web hosting subscription, set up a web server (like Apache or NGINX) to send your files, and then buy an SSL certificate to encrypt your traffic. That’s even before beginning to think about considerations of scale and geographic location. Netlify does this all, for the low, low price of free. It’s pretty amazing.
It’s important to note that your site is what’s called “static.” It’s got no backend — users can’t enter data or log in or out of your site and expect that state to be saved if they visit your site again. The reason Netlify can offer their service for free is because it’s become really, really cheap to send the same, static, unchanging files over and over again. Netlify can also compress that file (and since the original file stays the same, the compressed result stays the same, so it only needs to be compressed once, saving compute power) to save even more money.
Even though it’s cheap, it still costs something, and you may be wondering how Netlify makes money. They’re loss leading. Essentially, they hope that people like you and I sign up and really like the free plan. They also hope that we work for a big company and advocate for our company to use the product. Netlify’s paid plans offer a lot of features important to big companies — like team accounts, password-protected sites, and single-sign on. Their enterprise contracts likely more than make up for the free service they’re providing to us.
From personal experience, their strategy seems to be working — I use Netlify at work, and while we haven’t had to upgrade to a paid plan yet, we probably will soon as we host more and more websites on the platform.
Regardless, you should now be able to visit your site at [some string of text].netlify.com (like brave-curie-671954.netlify.com). Take a look! That’s your site — you can send that to your friends and family anywhere else in the world, and they’ll be able to see it too. Now, you just need your own personal domain.
This is the only part of this that costs money — at most $12/year, or $1/month. That is, you can buy 10 domains for the cost of your Netflix subscription. Not a bad deal at all.
A domain is the google.com, whitehouse.gov, lackawannacounty.org, or even abc.xyz that you see in your address bar. Domains are managed by centralized agencies — there’s a company that manages “.com”, another that manages “.gov” (that’s the U.S. Government’s General Services Administration), and more that manage “.org” and “.xyz”. The text that comes after the ”.” is called a top-level domain — so com, gov, org, and xyz are all top-level domains.
Whenever you type a domain into your address bar (like google.com) your browser contacts a DNS (domain name system) server (likely operated by your ISP, such as Comcast or Verizon) which tells it where that domain name is pointed at, which is typically an IP address.
Whereas “the Steamtown Mall” is like a domain name, “300 Lackawanna Ave, Scranton, PA 18503” is like an IP address. The post office needs to know the real address to send mail there, and your browser needs to know a real IP address to know where to send your request.
You have to register a domain through a company that’s authorized to work with the root company that manages all registrations for a specific top-level domain (for instance, to register a “.com”, you need to work with a company that’s authorized to work with Verisign, the company that manages all “.com” domains — a few examples would be GoDaddy, Namecheap, and Google Domains). A company that does this is called a registrar.
When you buy a domain, the registrar will send your domain registration to the root company, and then the root company will tell the world that you own a specific domain (and once you set it, that the domain points to a specific IP address). The server run by your ISP that your browser contacts to get domain information automatically updates and will eventually get this information, and then you’ll be able to type your domain into your browser and it will work.
I typically buy my domains from Namecheap — I bought my first domain from them when I was a freshman in high school since I didn’t have a debit card and they accepted bitcoin. I’ve used GoDaddy before but their UI and support was worse in my experience, and Google Domains seems fine if you want to use them, but if you’re new to this and just want to follow along, I’d recommend starting out with Namecheap.
First, search for your domain in Namecheap’s search bar. “com” is the most common top-level domain, so it’s usually a good place to start.
One downside of the popularity of “.com” is that the domain you want is often taken.
It’s disappointing, but domain squatting is a big business. Only one person in the world can own a specific .com, and there are people with portfolios of thousands of domains, bought at-cost for $10 or so dollars per year, that just wait and hope for someone to roll along and want to buy a domain desperately enough that they’ll pay enough to offset their entire sunk cost.
In our case, looking at other TLDs (.me and .co are pretty popular alternatives for personal websites) or searching for alternate domains is your best bet if your desired “.com” is taken (for a personal site, some alternatives to “first name last name” could be full name with middle initial, first initial last name, or just last name).
Once you’ve found an available domain you like, add it to your cart and then go the checkout screen. Namecheap usually has coupon codes available that you can use to get discounted registration, so try applying one in checkout before buying. After the purchase is complete, go to your Namecheap account dashboard.
Then, click the “Manage” button to the right of your domain to open the domain management screen.
You might have to verify your contact info for your domain to work, and if that’s the case, the “Manage” button in the image above will say “Verify Contacts”. Click the down arrow on the right side of that button — you should see a “Manage” link there instead that you can click.
You should get an email soon from Namecheap asking you to click a link to verify your information. After you do that, you’ll see “Manage” on the button as depicted above.
The default settings should be fine here. Next, go to “Advanced DNS” (all the way to the right).
You might have a few records already in the section labeled “Host Records.” Press the trash can on all of them to delete them (if the trash can doesn’t work, then just start editing the records directly by clicking the text that says “A Record” or “CNAME Record” under the “Type” column).
You’ll need to add the following records (or change the existing ones) to match below, making sure you change
your-site-name to your actual Netlify site ID (keep
188.8.131.52 exactly the same):
A Record @ 184.108.40.206 CNAME Record www your-site-name.netlify.com
You should have exactly two records set once you’re done.
The record associated with your “naked domain” (in this example,
dundermifflin.com without anything before of after, and denoted in DNS with the
@ sign) tells the browser the main IP address (“real address”) of the domain. This record must be an A record, and A records have to be IP addresses — it’s a limitation of DNS.
220.127.116.11 is the IP address of Netlify’s main load balancer (which will route your request to one of Netlify’s many servers that can send your website’s files).
www part of
www.dundermifflin.com) don’t have to be A records, and the CNAME here, which sets your
www subdomain, does not have to be an IP address. In fact, this is where Netlify’s magic comes in — the
your-site-name subdomain on
netlify.com which we’re setting here is also set in Netlify’s DNS, and they can set their own A record. Since we “delegate” the DNS to Netlify, Netlify can handle the logic on their end to return the IP address of the geographically closest server.
Customers accessing your naked domain will always have to send their traffic all the way to California (where
18.104.22.168 is located), but for me,
22.214.171.124, an IP address located in New York (I’m currently in Pennsylvania).
Use “5 min” for the TTL, and then make sure you save your records. After saving, when you access your domain in your browser, it might still not work, though — for a few reasons.
First, when you registered your domain, Namecheap sent your info to the centralized .com registry. If it hasn’t been much time, it’s likely that the centralized .com registry is still propagating the registration info to the local DNS server hosted by your ISP. It takes some time (sometimes as long as 48 hours) for that propagation to happen (ISPs have to query upstream, it’s not a push mechanism), so your ISP might just not know that your domain exists. There’s not much you can do other than wait.
Second, when you update your records here, your ISP’s local DNS servers have to get the updated DNS info from Namecheap in a similar way and it can take a similar amount of time. This behavior, however, is controlled by the TTL — “Time to Live” — that we’ve set.
For efficiency, DNS servers cache records (e.g. if you updated your record five seconds ago, ISPs won’t query again immediately because they can reasonably assume you haven’t changed it). A five-minute time-to-live means that your record will “die” after five minutes — that is, DNS servers will start re-querying five minutes after the last update. So the maximum amount of time you’ll have to wait to see the changes in your records reflected at home should only be five minutes going forward (after the initial propagation is done).
Although you’ve now told Namecheap to point your domain at Netlify (specifically, their main load balancer), Netlify hosts a lot of websites — you need to tell Netlify which domain is yours!
Log back into Netlify, click your site, and then hit “Settings” followed by “Domain Management” on the left.
The reason my site name doesn’t look like “brave-curie-671954” is because I manually changed it to “dundermifflin”. You can do the same by clicking the “Options” button to the right of your Netlify domain on this screen. If you do that, make sure to update the corresponding CNAME record in your DNS that we set in Namecheap earlier.
Then, click “Add custom domain.”
Since your domain has already been registered, Netlify will prompt you to confirm your ownership.
After you add the domain, to enable encrypted HTTPS connections to your site, you can scroll down and get an SSL certificate. However, these certificates depend on DNS being up-to-date (because it’s how your ownership of a domain is verified — you only can create certificates for domains you own. If you created a certificate for “google.com” you could potential decrypt the HTTPS traffic of all users of Google). So you might still need to wait a bit.
At this point, all it takes is patience — everything should be ready within 48 hours.
Hopefully you’ve waited — now visit your domain! You should see your real, working website with a professional custom domain. Throw it on your LinkedIn, Instagram bio, wherever — this is your website!
There are many like it, but this one is all yours.
To update your website with new changes you make on your computer, log into Netlify, click your site in the “Sites” list, and then click “Deploys” in the upper left.
Then, drag and drop your site folder onto the dotted rectangle just like before. Netlify will take care of the rest, and your site will update in just a few moments!
Add your email to get access to my latest work before anyone else. I also send occassional special surprises (like free domains). I don't send spam, and you can stop at any time.
If you liked "Playing in Traffic: How to Make a Professional Personal Website for Free", you might also like:
From application, to interview, to offer — my path to landing a full software engineering intern position at Google as a first-year student, my slightly unconventional hiring process, and a few resources I recommend for those going through the process now.
My 2020 Gap Year Playbook (for Startups and Tech)
As more and more colleges go online, I've started to get more questions from students about taking a gap year. If you're looking to take a gap year soon, willing to learn how to code, and interested in pursuing a career in tech, here's what I recommend.
Hi, I'm Nate. I taught myself how to code before college, and I entered the University of Michigan in the fall of 2018, where I discovered interests in math, economics, and personal writing.
College was a serious step up from what I was used to in high school, so one especially late night my second semester, while working on a problem set in the math atrium — I decided I had enough. I needed a break from school.
I began planning a gap year in Barcelona and reaching out to old web design clients from high school for contract software work. Those plans went out the window, though, when I miraculously landed an internship at Google for the coming summer.
So, when school let out in May, I flew out to San Francisco and moved into a place in the Mission District instead. I soon realized that much of what I was looking for in my gap year — the unparalleled personal and cultural growth that comes from living alone in an iconic, bohemian city; a hungry market for entrepreneurial software engineers — was right where I was in San Francisco.
In August, I officially disenrolled from my sophomore year of classes. I got my travel fix in September, zooming across America and visiting Los Angeles, Ann Arbor, Boston, Philadelphia, and Chicago as part of a ten-state excursion, before heading back to San Francisco by way of 52 hours on Amtrak.
In October 2019, shortly after the founders completed YC S19, I turned down my Google return offer and joined Jupiter as their first hire. Outside of establishing a strong engineering organization and codifying our guiding development philosophies and practices, I've spent the last few months building end-to-end systems with TypeScript, React, Kotlin, gRPC, and Kubernetes.
I started this little blog to share some of these experiences — I hope you enjoy.