RizTech Academy logo
RizTech Academy
Modern CSS and WorkflowLesson 5 of 525 min

Deploying a static site

A site on your laptop is a folder. A deployed site is a folder somebody else can reach. For static HTML and CSS the gap between those is about five minutes and costs nothing, which is worth knowing because most people assume otherwise.

What "static" means, and why it is easy

Your site is HTML, CSS, images and fonts. No server-side code, no database. So hosting is just serving files — which every hosting company does for free at the volumes a small site produces, because it costs them almost nothing.

Three consequences worth having:

It is fast by default. Files are served from a CDN — copies in data centres around the world — so a visitor in Pune is served from a nearby edge rather than from Virginia. That is latency you get without doing anything.

It barely breaks. There is no process to crash and nothing to run out of memory. The failure modes are a bad deploy or a DNS mistake, both of which you can undo.

It is genuinely free at this scale. Not a trial. A kirana shop's site will not approach any free tier's limits.

Git first

Before deploying, the site should be in Git. Not because deployment requires it — it does not — but because every good option deploys from Git, and because you want the history.

git init
git add .
git commit -m "The shop site"

A .gitignore worth having for a static site:

.DS_Store
Thumbs.db
node_modules/
*.log
.env

.DS_Store is the macOS folder-metadata file, and committing it is the most common giveaway of a first project. .env is there as a habit for later — never commit secrets, and for a static site remember that everything you deploy is public, including a file you forgot was in the folder.

Then create a repository on GitHub and push:

git remote add origin https://github.com/yourname/sharma-kirana.git
git branch -M main
git push -u origin main

Three ways to deploy

All three are free, all three deploy from Git, and all three give you HTTPS automatically.

GitHub Pages

The simplest if your code is already on GitHub. In the repository's Settings → Pages, choose the main branch and the root folder. A minute later the site is at yourname.github.io/sharma-kirana.

Two things to know. It serves from a subpath unless you use a custom domain, so root-relative links like /about.html break — they resolve to yourname.github.io/about.html. Either use relative links (about.html) or set a custom domain. This is the module 1 paths lesson arriving with consequences.

And add an empty .nojekyll file at the root, or GitHub runs your site through Jekyll and ignores any folder whose name starts with an underscore.

Netlify or Vercel

Connect the GitHub repository through their dashboard. For a plain static site, set the build command to nothing and the publish directory to . or wherever your index.html lives.

What you get beyond Pages:

  • A deploy preview for every branch and pull request, at its own URL. You can send somebody a link to a change before it is live, which is genuinely useful.
  • Instant rollback to any previous deploy from the dashboard.
  • Redirects and custom headers, which the next section needs.
  • Their own domain (sharma-kirana.netlify.app) plus a custom one.

Either is a good default. This site — riztechacademy.com — is on Vercel.

Cloudflare Pages

Same model, and worth mentioning because Cloudflare's network has good coverage in India, which matters for the audience this course keeps naming.

Custom domain

A .com costs roughly ₹800–1,200 a year; .in is often cheaper. Buy it from any registrar.

Then two DNS records, which is the part that confuses people the first time:

Type    Name    Value
A       @       <the host's IP>          ← the bare domain, sharmakirana.com
CNAME   www     <the host's hostname>    ← the www subdomain

@ means the domain itself. Your host tells you the exact values.

Three things to expect:

DNS propagation takes time — usually minutes, occasionally hours, because of the caching from module 1's lesson. If the old site is still showing, wait before changing anything else.

Pick one canonical form and redirect the other. www.sharmakirana.com and sharmakirana.com are different URLs to a search engine, and serving the same content at both splits your ranking. Every host has a setting for this.

HTTPS is automatic and free, via Let's Encrypt. There is no longer any reason for a site to be on http://, and browsers now mark it insecure.

Before you deploy: the checklist

Run this. It takes ten minutes and prevents the embarrassing version.

Content

  1. No lorem ipsum, no TODO, no placeholder phone number.
  2. Every page has a unique, specific <title> and a description.
  3. A favicon exists — otherwise a 404 on every page load.
  4. Open Graph tags with an og:image, so a WhatsApp share is a card and not a grey box.

Links and paths 5. Every internal link works from every page — including from a subfolder. 6. Every image loads. Check the Network tab for 404s rather than trusting your eyes. 7. File and folder names are lowercase with hyphens. Linux servers are case-sensitive even though your Mac is not, so About.html works locally and 404s live. This is the single most common first-deploy failure.

Performance 8. Images resized and in a modern format, with width and height. 9. loading="lazy" below the fold, and not on the hero. 10. Fonts self-hosted with font-display: swap, and at most one or two preloaded. 11. Lighthouse run on a throttled connection.

The module 4 and 5 passes 12. 320px with no horizontal scrollbar. 13. Tab through everything, with a visible focus ring. 14. axe or Lighthouse accessibility clean, in every state. 15. Dark mode, reduced motion and forced colours emulated. 16. Stylesheet off: does it still read as a document?

Housekeeping 17. No .DS_Store, no commented-out experiments, no console.log. 18. <html lang> set. 19. A robots.txt and a sitemap.xml if the site has more than a handful of pages.

After you deploy

Open it on your phone. Not device mode — the real thing, on mobile data if you can. Module 4's point: this is the only test that counts, and https:// behaviour differs from file:// in ways you have already been warned about.

Check the deployed URL, not localhost. Every first deploy has at least one path that worked locally and does not now.

Add analytics only if you will look at it. Something privacy-respecting and lightweight is preferable to Google Analytics for a small site — it is less script, fewer cookies, and no consent banner to build.

Set up a 404 page. A custom 404.html is picked up automatically by all three hosts, and it should have your navigation on it so a lost visitor can get somewhere.

Caching, and the one gotcha

Hosts serve your files with cache headers, so returning visitors do not re-download everything. Which produces the classic confusion: you deploy a CSS change and the site looks the same.

Usually the host handles this by fingerprinting filenames, and a hard reload (Ctrl + Shift + R, Cmd + Shift + R) confirms whether it is a cache issue. For a hand-written static site the simple fix is a version query:

<link rel="stylesheet" href="styles.css?v=3">

Crude, and it works. Bump it when you change the file.

The rule worth knowing: HTML should have a short cache lifetime, and assets a long one — because the HTML is what points at the assets, so a fresh HTML file can point at a new stylesheet name.

Keeping it alive

A deployed site is not finished.

Redeploying is one git push once it is connected. That is the whole reason to deploy from Git.

Check it occasionally. A domain expires, a font CDN disappears, an embedded map changes its API. A small site needs looking at perhaps twice a year.

Keep the repository tidy, because in six months it is the only documentation. A README saying what the site is, how to run it locally and how it deploys takes five minutes and saves an hour.

Check your work

Why static hosting is free. Serving files costs the host almost nothing at this scale.

What a CDN gives you. Lower latency, because a visitor is served from a nearby edge.

Why deploy from Git. One git push to redeploy, plus the history and previews.

The commonest .gitignore omission. .DS_Store.

What everything you deploy is. Public, including files you forgot were in the folder.

Two GitHub Pages gotchas. It serves from a subpath, so root-relative links break; and .nojekyll is needed for underscore-prefixed folders.

What Netlify and Vercel add over Pages. Per-branch deploy previews, instant rollback, redirects and headers.

The two DNS records. An A record on @ and a CNAME on www.

Why pick one canonical form. www and the bare domain are different URLs and split ranking.

The single most common first-deploy failure. Case-sensitive paths — About.html works on your Mac and 404s on Linux.

What to do immediately after deploying. Open it on a real phone, and check the deployed URL rather than localhost.

Why a CSS change appears not to deploy. Caching. Hard reload to confirm, then fingerprint or version the filename.

The caching rule. Short lifetime for HTML, long for assets.

Practice

  1. Put your site in Git with a sensible .gitignore and push it to GitHub.
  2. Deploy it with GitHub Pages. Note the URL.
  3. Find a root-relative link that breaks on the subpath, and fix it.
  4. Rename a file to About.html, link to it as about.html, and confirm it works locally. Then deploy and watch it 404.
  5. Deploy the same repository to Netlify or Vercel. Compare the two dashboards.
  6. Open a pull request and find the deploy preview URL.
  7. Roll back to a previous deploy from the dashboard.
  8. Run the full 19-point checklist and record what it caught.
  9. Run Lighthouse on the deployed URL with Slow 4G throttling. Compare with localhost.
  10. Open the deployed site on your phone, on mobile data.
  11. Share the link on WhatsApp and check whether you get a card or a grey box. Fix og:image if needed.
  12. Add a custom 404.html and visit a URL that does not exist.
  13. Change your CSS, redeploy, and see whether the change appears. Hard reload.
  14. Add ?v=2 to your stylesheet link and redeploy.
  15. If you own a domain, point it at the site and set up the canonical redirect. Note how long DNS took.
  16. Write a README saying what the site is, how to run it locally, and how it deploys.

Official documentation


You can now write modern CSS: custom properties as a design system, the selectors that replaced a pile of JavaScript, forms that look intentional, motion used with restraint, and a site that is actually online.

Next module: best practices — naming, organising, and code that survives somebody replacing your placeholder text with a real business name four words long.

Stuck on this lesson?

Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.

About the internship