Chapter 45 — Deployment: Hosting, Domains and CI Basics
Section 1 — What deployment actually means
Deployment is the process of taking the files you built on your own computer and putting them somewhere other people can reach through the web. Until you deploy, your site exists only for you. You can open it from a folder, show it to someone sitting beside you, and test it in your own browser, but nobody else can type an address and see it. Deployment changes that. It copies your finished files to a computer that stays switched on, stays connected to the internet, and is set up to answer requests from strangers. That computer, or the service that manages it for you, is called a host. The moment your files are on a host and linked to an address, your project stops being a private exercise and becomes a public site.
It helps to separate three ideas that beginners often blur together. Building is turning your source files into the files a browser can run. Hosting is storing those runnable files on a server that is always available. Publishing is making them reachable at an address people can use. You can build without hosting, for example when you preview a site locally, and you can host files without publishing them widely, for example when you share a preview link only with a reviewer. Deployment usually means doing all three in sequence: build, upload or copy, and then check that the live address actually works.
Deployment also forces you to think about which files matter. Your project folder may contain notes, drafts, editor settings, and source files that browsers never need. The deployed site should contain only what the browser needs: HTML, CSS, JavaScript, images, fonts, and any other assets the pages reference. Sending everything, including private notes or unfinished experiments, is untidy and can leak information you did not mean to share. A good deployment habit is to look at the deployed folder as if you were a stranger. Ask what each file is for, whether a visitor needs it, and whether it contains anything private. If you cannot answer, leave it out.
Another useful distinction is between deploying once and deploying repeatedly. A first deployment is exciting because it proves the whole chain works. Real work, however, is the tenth, fiftieth, and hundredth deployment. You fix a typo, add a page, change a colour, and deploy again. Each time, the live site should update cleanly, without breaking pages that already worked. That is why experienced developers automate deployment and keep careful notes about how a site is published. When deployment is a calm, repeatable routine rather than a frantic scramble, you can improve a site steadily instead of fearing every change.
Finally, deployment is where many small decisions become visible. A file name with a capital letter that worked on your computer may fail on a host that treats names as case-sensitive. A link that pointed to a file on your desktop will not work for anyone else. An image that was too large may suddenly feel slow on a real connection. None of this means you did the earlier work badly. It means deployment is a test of the whole project under real conditions.
Check: In your own words, what changes when a site is deployed?
Section 2 — From files on your computer to a live site
Imagine your site as a set of files in a folder on your computer. Inside that folder is usually an index file, which is the home page, plus stylesheets, scripts, images, and perhaps other pages. When you open the index file directly, your browser reads it from your own disk. Nobody else can do that, because nobody else has your disk. To make the site live, those files must travel to a host and be arranged in the same structure, so that links and references still resolve. If your home page expects a stylesheet at a path like styles/main.css, that file must exist at that same relative path on the host, or the page will load without styling. Deployment is therefore not just copying; it is copying with structure intact.
The journey usually has a few clear stages. First, you finish and test the site locally, checking that pages link correctly and that images load. Second, you prepare the files for the host, which may mean running a build step or simply selecting the folder that contains the finished site. Third, you transfer the files, either by connecting your code repository to the host so it deploys automatically, or by uploading them through a dashboard or a file-transfer tool. Fourth, the host serves the files: when a visitor requests your address, the host finds the matching file and sends it back. Fifth, you verify the live site yourself, in a fresh browser window, on a phone if possible, and through any links you expect visitors to use.
Relative paths deserve special attention at this stage, because they are the quiet cause of many deployment failures. A relative path says where a file is in relation to the current page, for example ../images/logo.png means go up one folder, then into images. That works only if the folder structure on the host matches the structure on your computer. An absolute path that starts with a slash, such as /images/logo.png, means start from the root of the site. Both approaches can work, but mixing them carelessly creates confusion, especially when pages live in different folders. Before deploying, open every page locally, click every link, and watch for missing images or unstyled pages.
You should also expect the live environment to differ from your computer in small ways. Your computer may ignore differences in capital letters in file names, while many hosts do not. Your local test may use a fast connection, while a visitor may use a slow mobile connection. Your browser may have cached an older stylesheet, making a change look invisible when it has actually deployed. Learning to clear the cache, test in a private window, and check the live address rather than your local copy will save you from chasing problems that do not exist. Deployment, in short, is a translation exercise: the same files, the same structure, but a new home, a new address, and real visitors.
A calm way to practise is to deploy a tiny test page before you deploy anything important. Put one heading, one paragraph, and one image on a page, deploy it, and confirm that all three appear live. If that works, your pipeline works.
Check: Why must the folder structure on the host match the structure on your computer?
Section 3 — The build step explained
Not every site needs a build step, but many modern front-end projects have one, and understanding it prevents a great deal of confusion. A build step is an automated process that takes your source files and produces a separate set of finished files ready for the browser. Your source might be organised for humans: many small files, readable names, comments, and tools that help you write code faster. The built output is organised for browsers and visitors: fewer files, smaller files, and everything in one output folder. You edit the source, run the build, and deploy the output.
What does a build actually do? The details depend on the tools you use, but the jobs are similar. It may combine many small stylesheets or scripts into fewer files, so the browser needs fewer requests. It may remove whitespace and comments to make files smaller, a process often called minification. It may convert newer language features into forms that older browsers understand. It may copy images and fonts into the output folder and give them unique names so browsers do not confuse an old version with a new one. It may also check for errors and stop if something is seriously wrong, which is useful: a failed build is a warning, not a disaster, and it is far better to catch a mistake before deployment than after.
The most important habit around builds is knowing which folder is which. Source folders often have names like src, while output folders are often called dist, build, or out. If you deploy the source folder by mistake, visitors may get unprocessed files, missing assets, or code that depends on tools that are not present on the host. If you edit the output folder directly, your fix will vanish at the next build. When a tutorial or a host asks for a publish directory, it is asking for the output folder, not the folder you edit. Write that directory name down in your project notes, because you will need it every time you connect a new host.
Builds can also fail for ordinary, fixable reasons. A missing file, a typo in an import, or a reference to a package that was never installed can all stop a build. The error message will usually name the file and the problem, even if the wording feels technical. Read the first error first, because later errors are often consequences of the first one. Fix it, run the build again locally, and only then deploy. Practising builds locally, before you involve a host, makes deployment far less stressful: you already know the build succeeds, so a deployment problem must lie elsewhere.
Finally, remember that a build step is a tool, not a requirement for every project. A small site made of plain HTML, CSS, and JavaScript needs no build at all, and adding one would only complicate it. Use a build when your project genuinely benefits from combining, shrinking, or converting files. When you do use one, treat its output as disposable: you can delete it and rebuild it at any time from the source. That mindset keeps your source as the single truth of the project, and deployment as a repeatable act of producing and publishing that truth.
Check: Why should you never edit built output files by hand?
Section 4 — Choosing a host for a static front end
A static front end is a site made of files that do not change per visitor on the server: HTML, CSS, JavaScript, images, and other assets served exactly as stored. Most beginner and many professional front-end projects are static in this sense, even when they feel interactive, because the interactivity happens in the visitor's browser rather than on the server. Choosing a host for such a site is therefore simpler than choosing a host for a complex application, but it still deserves thought. The right host is one that serves your files quickly, reliably, over HTTPS, and with a deployment method you can repeat without dread.
Start with the deployment method, because it shapes your daily experience. Some hosts connect to your code repository and deploy automatically whenever you push a change. Others let you drag a folder into a dashboard. Others expect you to upload files manually. Automatic deployment from a repository is usually the calmest long-term choice: you change code, push it, and the host builds and publishes it. Drag-and-drop is excellent for a quick experiment or a one-page demo, but it becomes tedious when you update often, because you must remember to upload the right folder every time. Manual upload through file transfer is still common on traditional shared hosting, and it works, but it places the burden of remembering every changed file on you.
Next, consider the address and HTTPS. Many modern hosts give you a free subdomain, such as yoursite.hostexample.com, and free HTTPS, which is essential for trust and for many browser features. Check whether you can later connect your own domain without paying for an expensive upgrade, and whether HTTPS is automatic or requires manual steps. A host that makes HTTPS difficult is a poor choice for a modern site, however cheap it seems. Also check where the host serves files from and whether it uses a content delivery network, which copies your files to servers around the world so visitors far away still load quickly.
Reliability and limits matter too, in plain terms. Read the free plan honestly: how much storage, how much monthly traffic, and how many sites are included? A tiny portfolio will fit almost anywhere, while a site with many large images or videos may hit limits quickly. Look for clear documentation and a status page, so you can tell whether an outage is your fault or the host's. Avoid hosts that require you to install unrelated software, accept confusing upsells, or lock your domain behind an awkward transfer process. You want a host you could leave if you needed to, which means keeping your domain registration separate from hosting when possible, a point later sections explain.
Finally, do not choose a host because it is fashionable; choose it because it fits this project. A portfolio, a documentation site, a landing page, and a capstone project all have different needs, but they share the same test: can you deploy in a few minutes, update in a few minutes, and verify the live result yourself? If the answer is yes, and HTTPS works, you have a good host. Deployment skill transfers between hosts far more easily than beginners expect, because the underlying ideas — files, folders, addresses, and HTTPS — stay the same.
Check: What should you check about HTTPS before choosing a host?
Section 5 — Previewing a production build locally
Previewing a production build locally means running the finished, built version of your site on your own computer, through a small local server, before you deploy it. This step catches a class of mistakes that opening files directly cannot catch. When you open an HTML file directly from disk, the browser uses a file address, not a web address, and some features behave differently: certain requests may be blocked, paths may resolve oddly, and routing may not work at all. A local server, even a very simple one, serves your files over a local web address, much closer to how a real host will serve them. It is the dress rehearsal before the performance.
The process is straightforward. First, build your project if it has a build step, so you have an output folder. Second, serve that output folder, not the source folder, with a simple static server tool. Many editors and command-line tools can do this with a single command, and the exact tool matters less than the principle: point the server at the built folder and open the local address it prints. Third, click through the site exactly as a visitor would. Check the home page, follow links to deeper pages, submit any forms that work without a server, resize the window, and test on a phone if you can reach the local address from it. Fourth, open the browser developer tools and look for errors and missing files. A missing stylesheet, a broken image, or a script error found here is a gift, because it costs nothing to fix before deployment.
Pay particular attention to paths during this preview. A site that works when opened as a single file may break when served from a folder, and a site that works from the root may break when a page lives in a subfolder. Previewing through a server reveals those problems immediately. Also watch for differences between development and production. In development, tools often inject helpers, show detailed errors, and reload automatically. In production, those helpers disappear, files are smaller, and errors may be quieter. A feature that depended on a development helper will fail silently in production, which is why the production preview exists: to test what visitors will actually receive.
Another benefit is performance honesty. A production build is usually smaller than development files, but it may still contain images that are far too large or scripts that load slowly. Previewing locally lets you feel that slowness before anyone else does, and it lets you measure page size and loading time without the noise of a real network. If a page feels heavy on your fast local machine, it will feel heavier on a visitor's phone. Fix the weight now, by resizing images or removing unused assets, rather than apologising for it later.
Make local production preview a non-negotiable step in your routine, especially before a first deployment or a large change. It takes a few minutes, requires no special account, and prevents the most common launch embarrassment: a site that worked perfectly in development and breaks the moment it goes live. Build, serve the output, click everything, check for errors, and only then deploy. That sequence will become second nature, and your launches will become noticeably calmer.
Check: Why is serving a build through a local server better than opening the file directly?
Section 6 — Deploying with GitHub Pages
GitHub Pages is a hosting service that publishes a static site directly from a GitHub repository. Its appeal for learners is clear: if your code already lives on GitHub, you can turn a repository into a live site without buying hosting or learning a separate upload process. You push your files, enable Pages, choose which branch and folder to publish, and GitHub serves the result at an address based on your username and repository name. For a portfolio, a project demo, or a documentation site, that simplicity is hard to beat, and it is why many teaching projects use it as a first host.
The setup has a few details worth getting right. First, decide what GitHub should publish. For a plain site with no build step, that is usually the main branch and the root folder, where your index file lives. For a project with a build step, it is usually a branch or folder containing the built output, not the source. Publishing the wrong folder is the most common GitHub Pages mistake: visitors see a repository listing, a blank page, or source files instead of the site. Second, confirm the file names. The home page must be called index.html, all lowercase, and links must match the exact capitalisation of the files they point to, because GitHub Pages is case-sensitive. Third, wait briefly after pushing: Pages needs a short time to build and publish, and checking too early can make a correct deployment look broken.
GitHub Pages also has limits you should understand before relying on it for something large. It is designed for static sites, not for server code, databases, or private back-end logic. It serves files, and any dynamic behaviour must happen in the browser or through external services. There are also size and usage limits, and the free address includes github.io in the name unless you connect your own domain, which Pages supports. For learning and for many small sites, those limits are generous. For a shop, a membership site, or an application with user accounts, you will eventually need a different kind of host, and that is normal: Pages is a starting point, not a universal answer.
A practical workflow looks like this. Keep your source in a repository, make a small change, commit it with a clear message, and push. Check the repository's Pages settings and its deployment history to confirm the new version published. Then open the live address in a private browser window and click through the changed pages. If something looks old, remember that browsers cache files; a hard refresh or a private window often reveals the new version. If something is missing, check the file path and capitalisation first, then check whether you published the right branch and folder. Most GitHub Pages problems yield to that short checklist.
Finally, treat GitHub Pages as a real host, not a toy. The live address is public, search engines may find it, and anyone with the link can see it. Do not publish private notes, secrets, or unfinished personal data there. When you are ready to share a project, however, Pages gives you a clean, repeatable path from repository to live site, and that path teaches the core deployment lesson better than any lecture: push, publish, verify, repeat.
Check: When using GitHub Pages, what should you publish: source files or built output for a project with a build step?
Section 7 — Deploying with Netlify Drop and Git
Netlify is a platform built around deploying front-end sites, and it offers two paths that suit different moments in a project. The first path, often called Drop, lets you drag a folder containing your finished site into the Netlify dashboard, and Netlify publishes it within moments at a generated address. The second path connects Netlify to your code repository, so every push can trigger a fresh deployment automatically. Both paths end in the same place — a live site over HTTPS — but they teach different lessons. Drop is perfect for a quick test; Git-connected deployment is the sustainable habit for a site you will update often.
Drop deserves a fair description, because beginners sometimes dismiss it as unserious. It is not. You build your site, locate the folder that contains the finished files, and drag that folder into the dashboard. Netlify uploads it, assigns an address, enables HTTPS, and gives you a link to check. If the folder is correct, the site works. If the folder is wrong — for example, you dragged the source folder instead of the built output — the site will look broken, and the fix is to drag the correct folder again. Drop is excellent for proving that a site deploys at all, for sharing a one-off demo, or for testing a design before you set up a repository. Its weakness is memory: Netlify does not know how you built the folder, so the next update requires you to remember to rebuild and drag again.
Git-connected deployment removes that weakness. You connect a repository, tell Netlify which branch to watch, which command builds the site if any, and which folder to publish. From then on, pushing to that branch starts a deployment. Netlify runs the build, publishes the output, and reports success or failure in its dashboard, with a log you can read. This is the pattern professional teams use in miniature: code is the source of truth, the platform builds it, and the live site is always traceable to a particular commit. If a deployment breaks, you can see exactly which change triggered it and roll back to an earlier deployment with a few clicks.
Netlify also adds conveniences that are worth knowing, even if you do not use them all at once. Preview deployments give every pull request or branch its own temporary address, so a reviewer can see a change before it reaches the main site. Redirect rules let you handle old addresses and single-page routing without server code. Form handling can capture simple form submissions without you building a back end, which is useful for a contact form on a static site, though it has limits and should not be treated as a general database. These features are optional; the core skill remains the same: publish the right folder, over HTTPS, and verify the result.
Choose Drop when you need speed and simplicity for a single share. Choose Git deployment when the site will live and change. Either way, verify after publishing: open the live address in a private window, click through the pages, and confirm that images, styles, and scripts all loaded. A deployment is not finished when the dashboard says it is; it is finished when a visitor's browser proves it.
Check: What is the main drawback of drag-and-drop deployment for a site you update often?
Section 8 — Deploying with Vercel and similar platforms
Vercel is another platform designed to make front-end deployment feel automatic, and it shares much of its philosophy with Netlify: connect a repository, let the platform build and publish, and get HTTPS and preview addresses without server work. It became well known alongside a popular JavaScript framework, but you do not need that framework to use it; plain static sites deploy there too. The lesson of this section is not to memorise one platform's buttons, which change over time, but to recognise the shared pattern across modern hosts: repository in, build command and output folder configured once, live site out, with every change redeploying automatically.
The first deployment on such a platform usually follows a short, reassuring sequence. You sign in, import a repository, and the platform guesses the project type, the build command, and the publish folder. Those guesses are often right, but you must check them, because a wrong publish folder is the fastest route to a blank or broken site. If your project has no build step, there may be no build command at all, and the publish folder is simply the folder containing your index file. If it has a build step, the platform must run that command and publish the output folder. After you confirm those settings, the platform builds, deploys, and gives you an address. Opening that address in a private window and clicking through the site is still your job; the platform cannot tell whether the design looks right or a link points to the wrong page.
Preview deployments are one of the most useful features on these platforms, and they deserve attention even for solo developers. When you work on a separate branch or propose a change, the platform can publish that branch at its own temporary address, leaving the main site untouched. You can share that preview link with a teacher, a client, or a friend, gather feedback, and only then merge the change into the main site. That separation protects visitors from half-finished work and protects you from the pressure of editing the live site directly. It also creates a habit worth keeping for your whole career: never experiment on the live site when you can experiment on a preview.
Similar platforms exist with different names and strengths, and you will encounter several across tutorials and jobs. Some emphasise speed, some emphasise simplicity, some integrate closely with a particular framework, and some focus on global delivery. For a static front end, the questions are always the same: does it build my project correctly, does it publish the right folder, does it provide HTTPS automatically, can I connect my own domain later, and can I roll back if a deployment goes wrong? If a platform answers yes to those questions and its documentation is clear, it is a reasonable choice for this kind of project.
Finally, remember that convenience does not remove responsibility. A platform that deploys automatically will also deploy mistakes automatically, including a typo, a broken link, or a file you did not mean to publish. That is why the verify step matters more, not less, as deployment gets easier. Push, wait for the build, read the log if it fails, open the live or preview address, and check the pages that changed.
Check: Why is a preview deployment safer than editing the live site directly?
Section 9 — Deploying with Cloudflare Pages and similar hosts
Cloudflare Pages is another host for static sites, and it is useful to study because it shows how hosting and global delivery fit together. When you deploy there, your files are not kept on a single computer waiting for visitors from everywhere. They are copied to many servers around the world, so a visitor is usually served from a nearby location. That idea is called a content delivery network, and it is why a site can feel fast in Lagos, London, and New York at the same time. You do not need to manage those copies yourself; the platform handles distribution, caching, and HTTPS for you, while you focus on the files and the address.
The deployment pattern will feel familiar by now. You connect a repository or upload a folder, confirm the build command if you have one, and confirm the output folder. The platform builds, publishes, and gives you an address to verify. What changes is mainly the dashboard and the extra features on offer, such as redirect rules, custom headers, and preview addresses for branches. Do not be distracted by a long feature list on your first deployment. The core test remains unchanged: does the home page load, do the links work, do the styles and images appear, and does HTTPS work? If those pass, the host is doing its job, whatever its brand name.
One feature worth understanding is how such hosts handle updates. When you deploy a new version, the platform does not instantly erase every old copy around the world. It replaces the source files and lets the distributed copies update, which usually happens quickly but is not always instant. That is why a visitor might briefly see an older version after you deploy. A private window, a hard refresh, or a short wait usually resolves it. If a change still does not appear after a reasonable wait, check that you deployed the correct branch and folder before assuming the platform is broken. Most apparent delays are either caching or a wrong folder.
Cloudflare Pages, like its competitors, also supports connecting your own domain, which later sections explain. The point for now is portability. Your HTML, CSS, and JavaScript do not belong to the host; they belong to your project. If you learn to deploy on one modern host, you can learn another in an afternoon, because the questions are the same and the files are the same. Choose the host whose documentation you understand, whose free limits fit your site, and whose deployment log you can read when something fails. Avoid locking yourself into features you do not need, such as a proprietary database or a special build trick, unless the project genuinely requires them. A portable static site is a site you can move, and that freedom is valuable as your work grows.
Check: What does a content delivery network do for visitors in different countries?
Section 10 — Shared hosting and uploading by file transfer
Shared hosting is the older, traditional way many small sites go live, and it is still worth understanding because you will meet it in jobs, client work, and cheap hosting plans. On shared hosting, many websites share one server, each in its own account and folder. You are usually given a control panel, a file manager, and login details for file transfer. You upload your finished files into a public folder, often called public_html or www, and the host serves them at your domain or a temporary address. There is no automatic build from a repository unless you set one up yourself; you are responsible for putting the right files in the right place.
File transfer usually means FTP or, preferably, SFTP, which is the encrypted version. A file-transfer program connects to the host with your credentials, shows your computer's files on one side and the host's files on the other, and lets you drag files across or synchronise folders. The encrypted version matters: plain FTP sends your login details in a readable form, which is unsafe on shared networks. Always choose SFTP when it is offered, and keep your credentials private, just as you would a password. If a host offers only plain FTP, treat that as a warning sign and consider whether the saving is worth the risk.
The main risk of manual upload is human error. It is easy to upload the wrong folder, forget a changed image, overwrite a file you meant to keep, or leave an old file that still links to a deleted page. A disciplined routine helps. Before uploading, build the site if needed and check it locally. Upload the whole finished folder for a first deployment, rather than guessing which files changed. For later updates, either re-upload the whole folder or keep a clear list of changed files and verify each one live afterwards. After every upload, open the live site in a private window and click through the pages you changed. That check is not optional; it is the deployment itself, in the sense that matters to visitors.
Shared hosting also has strengths. It is often inexpensive, it may include email and a domain in one package, and its control panel can feel familiar if you are used to managing files directly. Its weaknesses are speed of updates, lack of preview deployments, and the temptation to edit files directly on the server, which creates a version that exists nowhere else. If you edit live files directly, your local copy and the live site drift apart, and the next upload may undo your fix or reintroduce a bug. Keep your local project as the source of truth, upload from it, and never treat the server copy as your working copy. Used with that discipline, shared hosting remains a perfectly respectable way to publish a static site.
Check: Why is editing files directly on a shared host a bad habit?
Section 11 — When a front end needs a server
A purely static site needs only a host that serves files, but many front-end projects eventually need something more, and recognising that moment saves wasted effort. You need server help when the site must do something the browser alone cannot safely or reliably do. Examples include storing data that must persist for all visitors, such as comments or orders; sending an email from a contact form; checking a password before showing private content; or calling a paid service whose key must stay secret. In each case, the browser can collect input and display results, but a server must receive, check, store, or forward that data. The front end remains the interface; the server becomes the trusted worker behind it.
It is important not to overstate this need. A site that displays information, lets visitors search and filter it in the browser, and stores personal preferences on the visitor's own device does not need a server for those features. A calculator, a catalogue that loads from a public data file, a portfolio, and a documentation site can all be fully static. Beginners sometimes assume that any interactive feature requires a server, and then build unnecessary complexity. Ask a simple question for each feature: does this need to be shared between visitors, kept secret, or checked by someone the visitor cannot fool? If the answer is no, the browser can probably handle it. If the answer is yes, you need a server or a trusted external service.
When you do need server help, you have options that do not require you to become a back-end developer overnight. Many platforms offer serverless functions, which are small pieces of server code that run only when called, for example when a form is submitted. Form services can receive submissions and email them to you. Authentication services can handle sign-in without you storing passwords. A content management system or a headless service can supply data through an interface your front end can read. These tools let a front-end developer add server features in a limited, controlled way, while keeping the main site static. They also introduce new responsibilities, such as understanding what data the service stores and how it is protected, so choose them carefully.
A useful mental model is to think of the browser as untrusted territory. Anything in the browser can be inspected and changed by the visitor, because the visitor owns that device. That does not make visitors villains; it simply means the browser is the wrong place to enforce rules that matter, such as who may see private data or what price to charge. The server, which you control, is where those rules live. Your front end should therefore be honest about its role: it presents, it guides, it validates for convenience, but it does not pretend to be the final authority on sensitive decisions. Knowing where that line falls is one of the marks of a maturing front-end developer.
Check: Give one feature that needs a server and one that does not.
Section 12 — Domains: names you can own
A domain name is the human-readable address for a site, such as example.com, that visitors type instead of a numeric address. You do not buy a domain outright in the way you buy a book; you register the exclusive right to use it for a period, usually a year or more, and you renew that registration to keep it. While it is registered to you, you control where it points, which services use it, and which subdomains exist under it. When registration lapses, that control ends, and someone else may register it. Understanding that a domain is a rented name, not a permanent possession, explains why renewal reminders matter so much.
Domains have a structure worth learning. Reading from right to left, the last part is the top-level domain, such as .com, .org, or a country code like .ng. The part before it is the name you chose, such as example in example.com. Together, those form the registered domain. Anything before that is a subdomain, such as www or blog in blog.example.com. Subdomains let you organise services under one domain: a shop at shop.example.com, documentation at docs.example.com, and the main site at example.com itself, all controlled from the same domain settings. That organisation is free in the sense that creating a subdomain does not usually require a new registration, though your host must be configured to serve it.
A domain is separate from hosting, even when one company sells both. Hosting is where your files live; a domain is the name that points to them. Keeping those ideas separate helps you make better decisions. If your host becomes unsuitable, you can move your files and point your domain to the new host, without losing the address visitors know. If you let one company control both your domain and your hosting, and that company becomes difficult to deal with, moving becomes harder. Many developers therefore register a domain with a registrar they trust and host the site elsewhere, changing only the DNS settings, which later sections explain, when they move.
Choosing and managing a domain also involves responsibility. The contact details attached to a registration may be public unless privacy protection is used, so check what your registrar shows. A domain name is also part of your public identity: it appears in links, emails, and search results, and changing it later breaks old links and confuses visitors. That is why the next sections treat choosing a name carefully, rather than as a quick afterthought. A good domain is short, memorable, honest about what the site is, and one you are willing to renew and keep for years. Register it deliberately, note its expiry date, and keep its login details safe. Keep the renewal date somewhere you will actually see it, such as a calendar reminder.
Check: Why is a domain described as rented rather than bought outright?
Section 13 — Choosing a good domain name
Choosing a domain name feels creative, but it is mostly a practical decision about clarity and memory. A good domain is easy to say aloud, easy to spell after hearing it once, and easy to type without guessing. If you have to spell it letter by letter every time you mention it, or explain a clever pun, visitors will mistype it and give up. Shorter is usually better, but not at the cost of meaning. A name like kelicktechhub.com tells a visitor something, while a very short string of initials tells them nothing. Aim for a name that a stranger could remember after seeing it once and could guess how to spell without help.
Avoid common traps. Hyphens make a name harder to say and easier to mistype, because people forget whether a hyphen was present and where it sat. Numbers are similarly risky, because a listener cannot tell whether you mean the digit or the word, as in 4 versus for. Unusual spellings, double letters that are easy to miss, and words that sound alike but spell differently all create the same problem: the visitor arrives at the wrong site or nowhere at all. Test your shortlist by saying each name to a friend, asking them to write it down, and seeing whether they get it right. That five-minute test catches more problems than hours of staring at a list.
Also check the name in context. Say it as part of an email address, imagine it on a business card, and check whether it reads awkwardly when words run together without spaces. A name that looks fine with spaces can read very differently as a single string. Check whether the same or a very similar name is already used by a well-known site, a trademark, or a project in the same field, because confusion helps nobody and can create legal trouble. You are not expected to become a lawyer, but a quick search and a willingness to pick a different name when a clash is obvious will save you from an embarrassing rename later.
Finally, do not let perfection delay a project. Many beginners spend weeks hunting for an ideal domain while their site sits unpublished on a free subdomain. A free subdomain is a perfectly good home for learning, testing, and early sharing. When the project has a clear purpose and an audience, choose the best available domain from your shortlist, register it, and move on. You can keep the old address working as a redirect, so early links do not break. The domain supports the project; it is not the project. A clear, honest, pronounceable name, registered deliberately and renewed on time, will serve you far better than a brilliant name you never actually use.
Check: What simple test can you use to check whether a domain name is easy to remember?
Section 14 — Buying and renewing a domain
Buying a domain, more accurately registering it, starts with checking availability through a registrar, which is a company authorised to register domains. You type the name you want, the registrar tells you whether it is taken, and if it is free, you can register it for a chosen period, usually one year at a time, though longer periods are often offered. Prices vary by top-level domain and by registrar, and the first-year price is sometimes lower than the renewal price, so read the renewal price before you commit. A name that is cheap to start and expensive to keep can become an unwelcome surprise a year later.
During registration you will be asked for contact details, and you should provide accurate ones, because the registrar may need to reach you about renewal, transfer, or security issues. Many registrars offer privacy protection, which replaces your personal details in the public record with the registrar's details. For a personal project, that protection is usually worth enabling, because it reduces spam and unwanted contact. You will also create an account with the registrar, and that account deserves a strong, unique password and, where offered, two-factor authentication. Losing control of your registrar account can mean losing control of your domain, which is a serious problem for a live site.
Renewal is where many small sites quietly die. A domain does not renew itself unless you enable automatic renewal or pay for several years in advance. If it expires, the site stops working at that address, email at that domain stops working, and after a grace period the name may become available for someone else to register. Set a reminder well before expiry, keep your payment details and email address current with the registrar, and check that renewal emails are not landing in spam. Automatic renewal is sensible for a domain you intend to keep, provided you monitor the card it charges and the email it notifies. For a domain you are unsure about, a calendar reminder is the minimum.
Transferring a domain to another registrar is possible and is a normal part of managing a site, though it involves an authorisation code and a confirmation process designed to prevent theft. You do not need to master transfers on day one, but knowing they exist protects you from feeling trapped. Keep a simple record for each domain: registrar, account email, registration date, expiry date, renewal setting, and where the domain points. That one page of notes, kept privately and updated when anything changes, will prevent most domain emergencies. A domain is a small annual responsibility, and treating it as such keeps a live site live. A domain is a small annual responsibility, and treating it as such keeps a live site live, year after year.
Check: Why should you check the renewal price, not just the first-year price?
Section 15 — DNS in plain language
DNS, the Domain Name System, is the system that translates a domain name like example.com into the numeric address a computer needs to reach a server. Humans remember names; computers route by numbers called IP addresses. DNS is the directory that connects the two, much like a phone book connects a person's name to a number. When you type an address, your browser asks a DNS resolver to look up the name, receives an IP address in return, and then contacts that address. Without DNS, every site would require visitors to memorise strings of numbers, and the web as we know it would be unusable.
DNS works through records, which are entries that answer different kinds of questions about a domain. An A record answers the question, what IP address serves this name? A CNAME record answers, what other name should this name point to? A MX record answers, where should email for this domain go? Later sections explain A and CNAME records in detail, because those are the ones front-end developers change most often when connecting a domain to a host. For now, the key idea is that DNS is not a single file on your computer or a setting in your site's code. It is a distributed system, with records stored by your domain's DNS provider and copied, or cached, by resolvers around the world for speed.
Caching explains why DNS changes are not instant, a point worth understanding before you ever change a record. When a resolver looks up a name, it remembers the answer for a period set by the record's time-to-live, often called TTL. During that period, it will keep giving the old answer, even if you have changed the record. That is normal and by design: without caching, every visit would require a fresh lookup, and the system would be slow. It also means you should plan DNS changes calmly, make them before you need them to take effect, and avoid changing records repeatedly in a panic. Patience is part of DNS work.
Another useful distinction is between the registrar, the DNS provider, and the host. The registrar is where the domain is registered. The DNS provider is where the records live. The host is where the site's files live. Often one company provides all three, which can be convenient, but they are separate roles, and you can change one without changing the others. When a host gives you DNS instructions, it is telling you what records to create with your DNS provider so that the domain points to the host. You do not edit your HTML to point a domain somewhere; you edit DNS records. Keeping those roles clear turns a confusing dashboard into a set of simple questions: who holds my records, what should they say, and have I waited long enough for the change to spread?
Check: In plain language, what question does DNS answer for a browser?
Section 16 — Nameservers and where DNS lives
Nameservers are the servers that hold the authoritative answers for a domain's DNS records. When a resolver needs to find where example.com points, it eventually asks the domain's nameservers, and those servers give the current records. Think of nameservers as the official directory for a domain: other servers may hold cached copies, but the nameservers are the source that those copies came from. If you edit records in the wrong place, nothing changes live, because the world is asking a different set of nameservers. Knowing where your DNS lives is therefore the first step in any DNS task.
By default, DNS often lives with the registrar, which provides nameservers as part of registration. When you register a domain, the registrar sets its own nameservers for you, and you edit records in the registrar's dashboard. Many hosts, however, ask you to change your nameservers to theirs, so that DNS lives with the host instead. That is a common and legitimate setup: you keep the domain registered in one place, but you delegate DNS control to the host by pointing the nameserver settings at the host. After that change, you edit records in the host's dashboard, not the registrar's, and edits in the old dashboard will have no effect. That single fact explains many confused support questions.
Changing nameservers is simple in concept but slow in effect, like other DNS changes. You copy the nameserver addresses your host provides, paste them into the nameserver settings at your registrar, save, and wait for the change to spread. During that waiting period, some visitors may still reach the old nameservers and see old records. Do not make a second, contradictory change while the first is still spreading; you will only prolong the confusion. Note the time you made the change, check after a few hours, and use a DNS lookup tool if you want to see what different parts of the world are seeing. Those tools query resolvers in several locations and show whether the new nameservers are visible everywhere yet.
A safe habit is to record, for each domain, where DNS lives and where the site is hosted, in the same private notes where you record expiry dates. Write the nameserver addresses down, note the date of any change, and keep a screenshot or a copy of the previous settings until the new setup is confirmed working. If you ever need to move hosts again, those notes tell you exactly what to change and what to restore if something goes wrong. Nameservers sound technical, but the idea is ordinary: DNS answers come from one official place, and your job is to edit records in that place, not in a copy of it. That single fact explains many confused support questions, so check it first.
Check: Why do edits in the wrong DNS dashboard have no effect on a live site?
Section 17 — A records and pointing to a host
An A record is the simplest and most important DNS record for a front-end developer. It maps a domain name directly to an IP address, which is the numeric address of the server that should serve the site. When your host tells you to create an A record, it is giving you an IP address and asking you to associate that address with your domain, usually with the host name @, which stands for the domain itself, or with a subdomain name. Once that record exists and has spread, visitors who type your domain will be directed to that server. If the A record is wrong, visitors will reach the wrong server, or no server at all, even though your files are perfectly fine.
Creating an A record is a small act with a precise form. You open your DNS dashboard, choose to add a record, select type A, enter the host name, and paste the IP address exactly as the host gave it. A single mistyped digit sends visitors elsewhere, so copy the address rather than typing it from memory, and double-check it before saving. You may also need to set a TTL, which controls how long resolvers cache the answer. A shorter TTL means changes spread faster, but it also means more frequent lookups. For a first setup, the default TTL is usually fine; you would lower it deliberately before a planned move, so that the old address stops being used sooner.
A common confusion is between an A record and a CNAME record, which the next section covers. The short version is that an A record points to a number, while a CNAME points to another name. Hosts that give you a stable IP address will ask for an A record. Hosts that give you a hostname, such as yoursite.hostexample.com, will ask for a CNAME instead. Following the host's instructions literally is the safest approach: do not convert one type into the other because they look similar. If the instructions say A record, create an A record with the given IP; if they say CNAME, create a CNAME with the given name. Mixing them up is a frequent cause of a domain that stubbornly refuses to work.
After creating an A record, verify it before you announce the site. Wait a reasonable time, then use a DNS lookup tool to confirm that the record is visible and points to the expected address. Then open the domain in a private browser window and confirm that your site loads over HTTPS. If it does not load, check three things in order: is the IP address correct, did you create the record in the dashboard for the correct nameservers, and has enough time passed for the change to spread? Working through those questions calmly will resolve most A record problems without needing to change anything else.
Check: What does an A record map a domain name to?
Section 18 — CNAME records and subdomains
A CNAME record, short for canonical name, points one domain name to another domain name, rather than to an IP address. When a host asks you to create a CNAME, it usually gives you a target hostname, such as yoursite.hostexample.com, and asks you to point a subdomain, such as www, at that target. Visitors who type www.example.com are then directed, via that target name, to the host's servers. The advantage is flexibility: if the host changes its IP addresses behind the scenes, your CNAME still works, because it follows the target name rather than a fixed number. That is why many modern hosts prefer CNAME records, especially for subdomains.
CNAME records are also how subdomains are created in practice. To make blog.example.com, you create a record for the host name blog, pointing it where the blog should live. That destination might be the same host as your main site, a different platform entirely, or a service such as a newsletter or documentation tool. Each subdomain can therefore point somewhere different, while remaining clearly part of your domain. That flexibility is powerful, but it requires care: a subdomain you create and forget, pointing to a service you no longer use, can become a source of confusion or, in the worst case, a security risk if someone else claims the abandoned service. Keep a list of every subdomain you create and what it is for, and remove ones you no longer need.
There is one important rule about CNAME records: a name that has a CNAME record cannot have other records of most types at the same time. In plain terms, you cannot point www to a host with a CNAME and also give www its own email or other records, because the CNAME says, in effect, this name is exactly the same as that other name. That rule is also why a CNAME usually cannot be used at the root of a domain, the bare example.com without any subdomain. The root needs other records, such as those for email, so hosts handle root domains differently, often with A records or with a special flattening feature. The next section explains that root-domain problem in more detail.
When you create a CNAME, copy the target name exactly, including any trailing details the host specifies, and do not add extra characters. A target that looks almost right but contains a typo will fail silently, directing visitors nowhere useful. After saving, verify with a DNS lookup tool, wait for the change to spread, and then test the subdomain in a private window. If the main domain works but the subdomain does not, the CNAME is the first place to look: check its name, its target, and whether you edited the correct DNS dashboard. Those three checks solve most subdomain problems.
Check: What is the difference between an A record and a CNAME record?
Section 19 — Apex domains and www
The apex domain, also called the root or naked domain, is the domain without any subdomain: example.com, as opposed to www.example.com. Visitors use both forms, often interchangeably, and a well-set-up site should work on both, with one redirecting to the other so there is a single canonical address. Deciding which form is canonical is a choice, not a technical inevitability. Many sites choose the www form as canonical, while others choose the bare domain. Either can work, provided you set it up consistently and redirect the other form, rather than serving the same site from both addresses as if they were two different sites.
The apex presents a small technical puzzle. As the previous section noted, a CNAME record generally cannot sit at the apex, because the apex needs other records too. Hosts solve this in different ways. Some give you IP addresses and ask for A records at the apex, which works cleanly. Others offer a feature, sometimes called CNAME flattening or ANAME, that lets you enter a hostname at the apex while the DNS provider resolves it to addresses behind the scenes. Others ask you to use their nameservers, which handle the apex specially. The practical lesson is to follow your host's apex instructions exactly, rather than guessing. If the host says A records, use A records. If it says to use its nameservers or a special record type, follow that path and verify the result.
The www subdomain, by contrast, is straightforward: it is an ordinary subdomain, usually pointed with a CNAME to the host. Once both the apex and www are pointing correctly, you set up a redirect so that one form forwards to the other. That redirect matters for visitors and for search engines. Without it, someone who bookmarks the non-canonical form may land on a duplicate version of the site, links may split between two addresses, and analytics may count the same audience twice. With a redirect in place, every visitor ends up at the same canonical address, and old links keep working. Most modern hosts let you configure this redirect in a dashboard setting, without writing server code.
To check your setup, open both forms of the address in a private window: the bare domain and the www form. One should load the site directly, and the other should redirect to it, with the address bar changing to the canonical form. Also check that HTTPS works on both forms, because a certificate must cover both names. If one form works and the other shows an error, the problem is usually in DNS or in the redirect setting, not in your site's files. Fix the pointing first, confirm the redirect second, and your domain will behave as one site with two doors, which is exactly what visitors expect.
Check: Why should one of apex and www redirect to the other, rather than both serving the site separately?
Section 20 — DNS propagation and patience
DNS propagation is the time it takes for a DNS change to spread to resolvers around the world, so that everyone sees the new answer. It is not a single event, like flipping a switch, but a gradual process, because resolvers cache old answers until their time-to-live expires, and different resolvers check at different times. That is why a DNS change can appear to work for you within minutes, while a friend in another city still sees the old site hours later, or vice versa. Both of you are seeing correct answers for the resolvers you happen to use; you are simply seeing them at different stages of the spread.
How long propagation takes depends mainly on the TTL you set and on how widely the old answer was cached. A record with a short TTL, such as a few minutes, will generally update quickly, because resolvers discard it soon and fetch the new one. A record with a long TTL, such as a day, can take much longer to clear everywhere. Before a planned move, experienced developers lower the TTL well in advance, wait for the old long TTL to expire, and only then make the change, so the new answer spreads faster. You do not need to do this for a first setup, where there is no old answer to clear, but it is a useful habit to know for later moves.
Patience during propagation is not passive waiting; it is active, calm checking. Use a DNS lookup tool that queries resolvers in several locations, and note what each one returns. If most locations show the new record and a few still show the old one, the change is spreading normally, and waiting is the correct action. If no location shows the new record after several hours, something is wrong: you may have edited the wrong dashboard, mistyped the record, or set the wrong nameservers. That distinction — some locations updated versus none updated — is the most useful diagnostic you have. It separates a normal delay from a genuine mistake, and it prevents you from making a second change that only adds confusion.
Also avoid the temptation to keep editing during propagation. Each new edit restarts the waiting for that record, and a series of panicked changes can leave different resolvers holding different answers for a long time. Make one careful change, record the time, check a few locations after a sensible interval, and only revise if the evidence shows a mistake. Tell anyone waiting for the site that DNS can take time, and give them the new address to try later rather than promising an exact minute. DNS rewards careful preparation and calm waiting far more than speed, and learning that patience is part of becoming a reliable developer.
Check: Why might a DNS change work for you but not yet for a friend in another city?
Section 21 — HTTPS and why every site needs it
HTTPS is the secure version of the web's protocol, and the difference from plain HTTP is encryption plus authentication. With plain HTTP, the conversation between a visitor's browser and your server travels in a form that could be read or altered by anyone positioned in the middle, such as on a shared public network. With HTTPS, that conversation is encrypted, so an eavesdropper sees scrambled data rather than readable pages and form entries. Encryption also comes with a certificate that helps the browser verify it is talking to the site named in the address, not an impostor pretending to be that site. Together, those two protections — privacy and identity — are why HTTPS is now the baseline for every site, not an optional extra for shops and banks alone.
Visitors also judge HTTPS, even if they do not know the technical details. Modern browsers mark plain HTTP sites, especially those with forms, as Not Secure, and that label undermines trust before a visitor reads a single word. Search engines prefer secure sites, and some browser features, such as certain location and media capabilities, only work over HTTPS or on a local address. A site that asks for any input at all — a contact form, a search box, a sign-in — has a clear duty to protect that input in transit. Even a site with no forms benefits, because without encryption, the page itself could be altered on its way to the visitor, inserting unwanted content that neither you nor the visitor chose.
For a front-end developer, the practical rule is simple: never launch a site over plain HTTP if you can avoid it, and today you almost always can. Modern hosts provide HTTPS automatically, often at no extra cost, by obtaining and renewing certificates for you. When you connect a custom domain, follow the host's steps to enable HTTPS for that domain, and check that both the apex and www forms are covered. If a host charges extra for basic HTTPS, or makes it difficult to enable, consider that a serious drawback. There is rarely a good reason to accept a Not Secure label in order to save a small amount of effort or money.
Finally, HTTPS protects the journey, not the destination's honesty. A secure connection to a dishonest site is still a dishonest site; the padlock means the connection is private and the certificate matches the name, not that the content is true or the operator is trustworthy. That distinction matters when you teach others or judge sites yourself. HTTPS is a necessary foundation for trust, but it is not a guarantee of it. Build on that foundation with clear content, honest claims, and the other practices in this book, and your visitors will have good reason to trust both the connection and the site it delivers.
Check: What two protections does HTTPS provide that plain HTTP does not?
Section 22 — Certificates without the mystery
A certificate is a small digital document that lets a browser verify a site's identity and set up an encrypted connection. When a visitor opens an HTTPS address, the server presents its certificate, which contains the domain name it covers, the organisation or validation details, an expiry date, and a public key used to start encryption. The browser checks that the certificate was issued by an authority it trusts, that it matches the domain being visited, and that it has not expired. If those checks pass, the browser and server agree on encryption keys for the session and the padlock appears. If a check fails, the browser warns the visitor instead of quietly proceeding, which is the safe behaviour.
Certificates are issued by certificate authorities, organisations whose job is to verify, to a stated level, that the requester controls the domain in question. For most websites, the verification is simply proving control of the domain, for example by creating a DNS record or placing a file on the site as instructed. That level is called domain validation, and it is sufficient for the padlock and for encryption. Higher levels involve verifying an organisation's legal identity, which is relevant for some large institutions but unnecessary for a personal portfolio or a small project site. You do not need to understand every validation level to deploy safely; you need to know that domain validation proves control of the name, not the trustworthiness of the content behind it.
The good news for front-end developers is that you rarely need to buy or manage a certificate by hand. Many hosts obtain certificates automatically from a free, automated authority, install them, and renew them before they expire. That automation removed the old barriers of cost and expiry management that once kept many small sites on plain HTTP. Your job is usually to enable HTTPS in the host's dashboard, connect your domain correctly, and confirm that the certificate covers all the names you use, including www if you use it. If the host reports a certificate problem, check the domain pointing first, because a certificate cannot be issued for a name that does not yet point to the host.
Certificates expire, typically after a few months for automated ones, and renewal is therefore a recurring event, not a one-time setup. With automation, renewal happens silently, but you should still check HTTPS occasionally, especially after changing hosts or domains, because a broken renewal can turn a trusted site into a warning page overnight. If you ever see a certificate warning on your own site, do not tell visitors to ignore it; treat it as a deployment emergency, check the host's certificate status, and fix the pointing or renewal before sharing the link again. A certificate is not magic, but it is the mechanism that makes HTTPS trustworthy, and respecting its warnings protects your visitors.
Check: What does a browser check before showing the padlock for a site?
Section 23 — Redirects: www to non-www and old to new
A redirect is an instruction that tells a browser, when it requests one address, to go to a different address instead. Redirects are how you keep links working when addresses change, how you unify the www and non-www forms of a domain, and how you move a page without breaking every link that pointed to it. Without redirects, a changed address becomes a dead end: visitors see an error, search engines lose the page, and the goodwill built by the old link is wasted. With redirects, the old address remains useful as a signpost, quietly forwarding visitors to the right place.
The most common redirect for a front-end developer is the canonical redirect between www and the apex domain, covered in an earlier section. If your canonical address is example.com, then www.example.com should redirect there, and vice versa if you chose www as canonical. That redirect should be permanent, because you intend the canonical form to be the lasting address. Browsers and search engines treat a permanent redirect as a lasting instruction, updating bookmarks and search results over time. A temporary redirect, by contrast, says the move is only for now, and it is appropriate when a page is briefly unavailable or when you are testing a change. Using the wrong type is not catastrophic for a small site, but using the permanent type for a lasting move is the correct, professional habit.
Redirects also matter when you rename or move pages. If a guide moves from /guides/html-basics to /learn/html-basics, a redirect from the old path to the new one preserves links from other sites, bookmarks, and social posts. On modern static hosts, you configure such redirects in a dashboard or a small configuration file, listing the old path and the new path. You do not need server code for simple cases. Keep the list tidy: redirect to the closest matching new page, not always to the home page, because sending a visitor who wanted a specific guide to a generic home page feels like a broken link with extra steps. If no close match exists, a helpful custom error page, covered next, is better than a misleading redirect.
Testing redirects is straightforward and worth doing after any change. Open the old address in a private window and watch the address bar: it should change to the new address, and the new page should load over HTTPS. Check both the www and non-www forms, and check a moved page if you created one. Also avoid redirect chains, where one address redirects to another, which redirects to a third; each hop slows the visit and increases the chance of failure. Aim for one hop from any old address directly to its final destination. Redirects are quiet infrastructure, but they are what make a site feel stable over time, even as its structure evolves.
Check: Why should a moved page redirect to its closest new page, not always to the home page?
Section 24 — Custom 404 pages
A 404 error means the server could not find the page at the requested address. It happens for ordinary reasons: a visitor mistypes an address, follows an old link to a deleted page, or clicks a link that was never correct. The default 404 page provided by a host is usually stark and unhelpful, telling the visitor only that something is missing. A custom 404 page replaces that dead end with guidance: a clear message in plain language, a link back to the home page, a search box or a list of popular pages, and the same header and navigation as the rest of the site. It does not pretend the missing page exists; it helps the visitor recover from the mistake.
Designing a good 404 page is an exercise in empathy. The visitor arrived with an intention — to read a guide, view a project, or contact you — and that intention has been frustrated. Your page should acknowledge the problem without blaming the visitor, because the fault may be yours, in the form of a broken link, or may simply be a typo. Use a friendly heading such as Page not found, explain briefly that the address may have changed or been mistyped, and offer concrete next steps. A search box is especially useful on a content site, because it lets the visitor find what they wanted without starting over from the home page. Keep the tone consistent with the rest of the site; a joke is fine if it fits your voice, but clarity must come first.
Technically, a custom 404 page on a static host is usually a file named 404.html at the root of the published folder. When the host cannot find a requested file, it serves that page instead, while still reporting the 404 status to the browser and to search engines. That status matters: it tells search engines the page is genuinely missing, so they do not index your error page as if it were content. Do not redirect all missing pages to the home page as a substitute for a 404 page, because that hides the error and confuses both visitors and search engines. A visitor who wanted a specific guide and lands on the home page without explanation may assume the guide was removed, or may simply leave.
To test your 404 page, visit a deliberately wrong address on your live site, such as yourdomain.com/this-page-does-not-exist, in a private window. Confirm that your custom page appears, that navigation works from it, and that the browser still reports a 404 status if you check developer tools. Also fix the underlying cause when you can: if you find a broken link on your own site, repair it; if an external site links to a deleted page, add a redirect for that path. A custom 404 page is a safety net, not a substitute for correct links, but every site needs a safety net, because typos and old links are inevitable.
Check: Why should a missing page return a 404 status instead of redirecting to the home page?
Section 25 — Single-page app routing on a host
A single-page application, often called an SPA, is a site where JavaScript loads one HTML file and then changes the view in the browser as the visitor navigates, without requesting a new page from the server for each view. The address bar still changes, so a visitor can bookmark a view like /catalogue or share it with a friend, but those addresses do not correspond to separate HTML files on the host. That design creates a deployment problem: if a visitor opens /catalogue directly, or refreshes the page while on that view, the host looks for a file at that path, finds nothing, and returns a 404 error, even though the application could have shown the catalogue view perfectly well from its single HTML file.
The standard solution is a fallback rule, sometimes called an SPA fallback or a rewrite. It tells the host: if no file matches the requested path, serve the main HTML file instead, and let the application's JavaScript decide what to show. The visitor still sees the correct view, the address bar keeps the requested path, and a refresh works. This rule is configured differently on each host — a dashboard setting on some, a small configuration file on others — but the idea is identical everywhere. Without it, an SPA works only when visitors start at the home page and navigate from there; with it, every view becomes a real, shareable address.
It is important to distinguish a fallback from a redirect. A redirect changes the address bar to the home page, losing the requested view, and the visitor must navigate again. A fallback keeps the address bar unchanged and serves the application file with a success status, so the application can read the path and render the right view. That distinction matters for usability and for sharing: a shared link should open the shared view, not the home page. It also matters for search engines, though SPAs have separate challenges with indexing that are beyond the scope of a first deployment. For now, the rule is simple: if your app uses client-side routing, configure the fallback before you share any deep link.
Testing SPA routing is easy once you know what to look for. Deploy the app, open the home page, navigate to a deeper view, copy its address, paste it into a fresh private window, and press Enter. If the deeper view loads directly, the fallback works. Then refresh that view and confirm it still loads. If either test shows a 404 page, the fallback is missing or misconfigured, and you should check the host's documentation for its SPA setting. Also test a genuinely wrong address: it should show your application's not-found view, not the host's default error, because the fallback hands all unmatched paths to your app. That behaviour is correct for an SPA, provided your app handles unknown paths gracefully with a helpful message and links back to real views.
Check: Why does refreshing a single-page app view sometimes show a 404 error without a fallback rule?
Section 26 — Environment variables on the front end
Environment variables are named values that change depending on where code runs, such as development on your computer versus production on a host. A common example is the address of a data service: during development you might point to a test service, while in production you point to the live one. Instead of editing code every time you deploy, you store the address in an environment variable, and the build or the host substitutes the correct value for each environment. That separation keeps code stable while its configuration changes, which is exactly what you want when the same project runs in several places.
On the front end, there is a crucial limit to understand: anything built into front-end code is visible to visitors. When a build substitutes an environment variable into JavaScript, that value ends up in a file the browser downloads, and anyone can read it by inspecting the site. That does not make environment variables useless; it makes them suitable only for values that are safe to be public, such as a public data address, a feature flag, or a non-secret project identifier. It makes them entirely unsuitable for passwords, private API keys, or any credential that must stay secret. A secret that reaches the browser is no longer a secret, however it got there, and no build tool can change that fact.
Hosts and CI systems provide a dashboard or settings area where you define environment variables for each deployment, and builds read them during the build step. You set a name, such as DATA_URL, and a value for production, and the platform supplies it when building. Different platforms use different prefixes to decide which variables may be embedded in front-end code, and their documentation explains the convention. Follow it carefully, and never assume a variable is private simply because you set it in a dashboard: if your code embeds it in the output, it becomes public. The dashboard setting controls who can edit the value, not who can read the built result.
A safe workflow looks like this. List every value your front end needs that might differ between environments. For each one, ask whether it is safe for the whole world to see. If yes, use an environment variable and document its name and purpose in your project notes, without writing the production value into those notes. If no, do not put it in front-end code at all; keep it on a server or in a trusted service that the front end calls, so the secret never travels to the browser. That single question, asked for every variable, prevents the most common deployment security mistake, which the next section examines more closely. Configuration should make deployment easier, not leak what you meant to protect.
Check: Why is a value built into front-end JavaScript never truly private?
Section 27 — What never belongs in front-end code
Some things must never appear in front-end code, in a repository, or in a deployed bundle, because the browser gives them to anyone who asks. Private API keys, passwords, database credentials, signing secrets, and personal access tokens all belong in this category. A beginner sometimes pastes a key into JavaScript to make a service work quickly, intending to remove it later, and then forgets. Once that code is pushed to a repository or deployed, the key is exposed, and removing it from the current version does not undo the exposure: copies may exist in version history, in caches, or in downloads made while it was live. The only safe response to an exposed secret is to revoke it and replace it, not merely to delete it from view.
The reason is structural, not a matter of obscurity. Front-end code is delivered to the visitor's device, and the visitor can inspect every file, search for suspicious strings, and read values that the code uses. Hiding a key in an obscure file, splitting it into pieces, or encoding it does not protect it, because the browser must reassemble it to use it, and anyone inspecting the code can follow the same steps. Security through obscurity fails here for a simple reason: the attacker has the same code you gave the browser, and the same tools to read it. If a service's documentation says a key must be kept secret, that key must never be embedded in front-end code, however convenient it would be.
What, then, should you do when a feature needs a secret? Keep the secret on a server you control, or use a service designed for browser use with a public, limited key. For example, a contact form can send data to a server function that holds the email credentials, while the browser only sends the form contents. A map that requires a key can often use a restricted public key that is limited to your domain and to specific services, which is a different kind of credential from a private key, and its documentation will say so. When in doubt, read the service's documentation for the words public and private, and treat anything labelled private or secret as forbidden in the browser. If the documentation is unclear, ask before you ship, rather than guessing.
Also audit your project before every deployment for accidental secrets. Search the code for words like key, secret, token, and password, and check each match to confirm it is not a real credential. Check that configuration files containing secrets are excluded from version control, using an ignore file, and that example configuration files contain placeholders, not real values. Keep a private record of where each real secret lives, who can access it, and how to revoke it. That discipline, practised on small projects, becomes second nature on larger ones, and it protects both you and your users from a mistake that is easy to make and painful to undo.
Check: If you delete an exposed secret from your code, why is that not enough to make it safe again?
Section 28 — Caching: why visitors see old versions
Caching is the practice of storing a copy of a file so it can be reused without downloading it again, and it is one of the main reasons visitors sometimes see an old version of your site after you deploy a new one. Browsers cache stylesheets, scripts, and images, hosts and delivery networks cache pages, and each cache holds its copy for a period set by headers or by default rules. Caching is beneficial: it makes repeat visits faster, reduces traffic, and improves the experience on slow connections. It becomes confusing only when you expect a change to appear instantly and a cache somewhere still serves the previous version.
To diagnose a stale version, work through the caches in order. First, check whether you actually deployed the new version, by looking at the host's deployment history and confirming the latest build succeeded. Second, open the live site in a private window, which uses a fresh cache, and compare it with your normal window. If the private window shows the new version, your browser cache is the culprit, and a hard refresh or clearing the cache will reveal the update. Third, consider the host's cache: some hosts and delivery networks take a short time to replace distributed copies, especially after a large deployment. Waiting a few minutes and rechecking often resolves that case without any action on your part.
Understanding cache headers helps you reason about this without guessing. A header can tell a browser to cache a file for a long time, to revalidate it on each visit, or never to cache it at all. Long caching is excellent for files that rarely change and whose names change when they do, a technique the next section explains. It is poor for an HTML file that changes often but keeps the same name, because visitors may keep receiving the old page. Hosts set sensible defaults for many cases, and you do not need to master every header on day one, but you should know that caching is controlled, not random, and that a stale page usually has a specific cache somewhere that explains it.
The practical habit is to expect caching and plan for it. After deploying, verify in a private window, not just in the window you used for development, which may hold old files. When you report a deployment to others, warn them that they may need to refresh if they visited recently. When a change is urgent, such as fixing a serious error, use the host's cache-clearing option if it offers one, rather than deploying the same files repeatedly in frustration. Caching is not your enemy; it is a performance feature that requires a little patience and a clear checking routine to work with comfortably.
Check: What is the first cache you should rule out by using a private window?
Section 29 — Cache busting with hashed filenames
Cache busting is the technique of ensuring that when a file changes, browsers treat the new version as a different file, rather than reusing a cached old version. The most reliable method is to include a hash, a short string derived from the file's contents, in the file's name. For example, a stylesheet might be published as main.a3f9c2.css, where the middle part changes whenever the stylesheet's contents change. The HTML page references that exact filename, so when the contents change, the reference changes too, and the browser downloads the new file because it has never seen that name before. The old file, with its old hash, can safely remain cached, because nothing references it any longer.
This approach works because it turns caching from a problem into an advantage. Files with hashed names can be cached for a very long time, even a year, because a changed file is never served under the old name. That means repeat visitors download each asset once and reuse it confidently, while still receiving updates promptly when the HTML points to new hashed names. The HTML file itself, which contains those references, is usually cached for a short time or revalidated on each visit, so that visitors pick up the new references quickly. That combination — long-lived assets, short-lived HTML — is the standard pattern for performant, reliably updating sites.
Build tools usually handle hashing automatically. When you run a build, the tool generates hashed filenames, updates the references in your HTML and other files, and places the results in the output folder. Your job is to deploy the whole output folder, including the HTML that references the new names, and not to mix old and new files. Deploying only a changed stylesheet without its updated HTML, for example, would leave the site pointing at the old hashed name, and visitors would see no change. Deploying the complete output as a set keeps the references consistent, which is why earlier sections emphasised publishing the whole output folder rather than individual files.
You do not need to invent hash strings by hand, and you should not rename files manually to fake a change. A hash must reflect the contents, so that identical contents produce identical names and different contents produce different names; a manual rename that does not follow that rule creates confusion without guaranteeing an update. Trust the build tool to generate hashes, verify after deployment that the live HTML references the new filenames, and check in a private window that the new styles or scripts are actually loading. When those checks pass, cache busting has done its quiet job: fast repeat visits, prompt updates, and no more arguments with a stubborn browser cache.
Check: Why does changing a file's hashed name force a browser to download the new version?
Section 30 — Headers every front-end developer should know
Headers are pieces of metadata sent along with a web response, invisible in the page itself but influential in how browsers treat it. You do not need to memorise every header, but knowing a handful will help you understand caching, security, and content handling, and will make host documentation far less intimidating. Think of headers as instructions attached to a file: they do not change the file's content, but they tell the browser how long to keep it, what type it is, and what it is allowed to do. A host sets many headers by default, and some hosts let you customise them.
The content type header tells the browser what kind of file it received, such as HTML, CSS, JavaScript, or an image. If this header is wrong, a browser may refuse to run a stylesheet or script, or may display a file as text instead of rendering it. That is why a page that looks correct locally can break when served with the wrong content type, and why hosts must be configured to serve files with correct types. You will rarely set this header yourself for a static site, because the host infers it from the file extension, but recognising it helps you diagnose a file that downloads instead of displaying, or a script that the browser refuses to execute.
Cache headers, discussed in the previous sections, tell the browser how long to keep a file and when to check for a new version. Security headers, covered in more depth in the security chapter, tell the browser to prefer HTTPS, to limit which sites may embed your page, and to restrict which sources may load scripts and styles. A redirect header tells the browser to go to a different address, and a status code, while not strictly a header, travels with the response to say whether the request succeeded, redirected, or failed. Together, these headers form a small language of instructions that surround every page load, and learning to inspect them in developer tools is a valuable skill: open the network panel, click a request, and read its headers to see exactly what the server said.
You do not need to set exotic headers for a first site. The practical steps are to use a host that sets sensible defaults, to check that HTTPS and caching behave as expected, and to add simple custom headers only when a host's documentation gives you a clear reason, such as a security header for a production site. Avoid copying a long list of headers from a tutorial without understanding each one, because a wrong header can block legitimate content or break a feature. Learn the few that matter, inspect them when something behaves oddly, and let the host handle the rest until your project genuinely needs more control.
Check: What does a content type header tell a browser about a file?
Section 31 — Performance checks before you deploy
Performance is how quickly a site becomes usable, and it should be checked before deployment, not after visitors complain. A site that feels fast on your computer and fast connection may feel slow on a phone with a weaker connection, a smaller processor, and a data limit. Checking performance before launch is therefore an act of respect for real visitors, many of whom will not have your setup. It is also easier to fix problems before launch, when you can resize an image or remove an unused script without worrying about breaking a live audience's bookmarks or habits.
Start with the largest and most common culprit: images. Check the size of every image file, not just its display size on screen. An image that displays at a few hundred pixels wide but is stored at several thousand pixels wide wastes download time and memory. Resize images to close to their display size, choose a suitable format, and compress them without visibly harming quality. Next, check the total size of each page, including stylesheets, scripts, fonts, and images. A page that totals several megabytes will struggle on a slow connection, while a page under a megabyte will usually feel responsive. You do not need to hit an arbitrary number, but you should know your total and be able to justify every large file in it.
Then check how many requests each page makes and what blocks rendering. Every stylesheet, script, font, and image is a request, and while modern browsers handle many requests well, a page with dozens of unnecessary files will still suffer. Remove unused stylesheets and scripts, combine files where your build tool does so, and avoid loading a large library for a tiny feature that plain code could handle. Check that scripts that are not needed immediately do not block the first display, and that fonts have a sensible fallback so text appears promptly even if a web font is slow. Use the browser's developer tools to see a waterfall of requests and to identify the slowest ones; the slowest file is usually where your effort should go first.
Finally, test on a realistic device and connection, not only on your development machine. Open the production preview on a phone, ideally over a mobile connection or with network throttling in developer tools, and notice when the main content becomes readable and interactive. If that moment feels slow, fix the largest problem first and retest, rather than making many small tweaks at once. Performance work is iterative: measure, fix the biggest issue, measure again. A site that loads promptly and becomes interactive quickly earns trust, and that trust is part of what deployment is for. Small fixes, measured one at a time, add up to a noticeably faster site.
Check: Why should you check an image's file size, not just its display size?
Section 32 — Images and assets in deployment
Images and other assets — fonts, icons, videos, documents — deserve careful handling at deployment time, because they are often the largest files a site serves and the easiest to break with a wrong path. An asset that loads locally but not live usually has one of a few causes: the file was not included in the deployed folder, its path is wrong for the page that references it, or its filename capitalisation differs from the reference. A systematic check catches all three: confirm the file exists in the output folder, confirm the reference matches its path and spelling exactly, and confirm the live page loads it in a private window. That checklist, applied to every asset, prevents most deployment embarrassments.
Organisation helps before deployment even begins. Keep assets in a clear folder structure, such as images, fonts, and documents, with lowercase, descriptive filenames and no spaces. Spaces in filenames cause encoding problems in addresses, and capital letters cause case-sensitivity problems on many hosts. A file named Team Photo.JPG referenced as team-photo.jpg will fail on a case-sensitive host, even though it worked on a computer that ignores case. Renaming files early, to a consistent convention, is a small effort that pays off at every deployment. Also avoid extremely long filenames and special characters, which can cause trouble in different tools and systems.
Size and format decisions also belong in deployment planning. A photograph that is several megabytes will slow every page that uses it, and a video hosted directly on a static site can quickly exhaust storage and traffic limits. For large media, consider whether the file should be resized, compressed, converted to a more efficient format, or hosted on a dedicated media service and embedded, rather than served as a raw file from your site. For icons and simple graphics, a vector format often scales cleanly at a tiny file size, while photographs suit compressed raster formats. The right choice depends on the content, but the principle is constant: serve the smallest file that still looks good at its display size.
Finally, remember licensing and ownership for assets you deploy. Only publish images, fonts, and other media you have the right to use, whether you created them, licensed them, or obtained them under a permissive licence that allows your use. A deployed site is public, and using someone else's work without permission becomes visible in a way that a private practice project does not. Keep a note of where each asset came from and what licence applies, especially for fonts and stock images. Clean organisation, correct paths, sensible sizes, and clear rights together make assets a strength of a deployed site rather than a recurring source of broken images and slow pages.
Check: What are the three most common reasons a live image fails to load?
Section 33 — Forms without a back end
A form on a static site presents a puzzle: the browser can collect input, but a static host has no server code to receive it, store it, or email it. That does not mean forms are impossible without a back end; it means the submission must go somewhere else that can handle it. Common solutions include a form-handling service, a serverless function, or an email service designed for static sites. In each case, the form in your HTML points to an external address, the visitor submits, and that service receives the data and acts on it, for example by emailing you or storing the entry in a dashboard you can review. Your front-end job is to build a clear, accessible form and to point it correctly, not to pretend the static host itself processes submissions.
Design the form first, before choosing a service. Decide what information you genuinely need, keep the number of fields small, label every field clearly, and explain what will happen after submission. A contact form that asks only for a name, an email address, and a message is more likely to be completed than one that demands unnecessary details. Add helpful validation in the browser, such as checking that a required field is filled and that an email address looks plausible, while remembering that browser validation is for convenience, not security; the receiving service must do its own checks. Also design the success and error states: after submission, the visitor should see a clear confirmation, and if something fails, they should see a helpful message and a way to try again or contact you another way.
When you choose a form service, read its terms and limits honestly. How many submissions are included, where is the data stored, how long is it kept, and who can access it? A free plan may be generous for a portfolio but inadequate for a busy site. Also consider privacy: if the form collects personal data, visitors should know what you will do with it, and you should not collect sensitive information through a simple form service at all. Test the form end to end before launch, using a real submission, and confirm that you receive it and that the visitor sees the confirmation. A form that looks finished but never delivers is worse than no form, because it silently loses messages from people who trusted it.
Finally, protect the form from spam without punishing real visitors. Many form services offer a simple anti-spam check, such as a hidden field that automated bots fill but humans do not, or a challenge that appears only when behaviour looks suspicious. Avoid aggressive challenges on every submission, which frustrate legitimate users, especially those using assistive technology. Monitor submissions after launch, reply promptly, and keep the form's purpose narrow. A static site can offer a genuinely useful form, provided you are honest about where submissions go and you test the whole journey, from typing to receipt, before you invite anyone to use it.
Check: Why cannot a purely static host process a form submission by itself?
Section 34 — Preview deployments and staging sites
A preview deployment is a temporary, live version of a site built from a branch or a proposed change, separate from the main live site. A staging site is a longer-lived copy of the site used for testing before changes go to production. Both serve the same purpose: let people see and test a change in a real, hosted environment without risking the site that visitors currently use. The difference is mainly duration and intent. A preview is tied to a specific change and disappears when that change is merged or discarded. A staging site persists as a standing test environment, where several changes can be checked together before a release.
Preview deployments change how feedback works. Instead of describing a change in words, or sending screenshots that cannot be clicked, you share a link to a working version. A teacher can click through a new page, a client can test a form, and a colleague can check a layout on a phone, all without touching the live site. That makes feedback concrete and catches problems that screenshots hide, such as a link that goes nowhere or a layout that breaks at a particular width. It also protects the live site from half-finished work: a change that turns out to be wrong never reaches visitors, because it lived only on its preview address.
Staging sites add a place to test combinations. A single preview may test one feature well, but a release often combines several changes, and those changes can interact in unexpected ways. Staging lets you deploy the combined result, run through key journeys — home page, search, form, navigation on a phone — and confirm that the whole still works before you promote it to production. Staging should mirror production as closely as possible: same host type, same configuration, same content structure, though it may use test data instead of real user data. The closer the mirror, the more trustworthy the test. A staging site that differs wildly from production can give false confidence.
Both approaches require a small discipline: keep preview and staging addresses out of search results and public promotion, so visitors do not bookmark a test version by mistake. Many hosts offer settings to discourage indexing of previews, and you should use them. Also remember that a preview or staging site is still a deployment: do not put real secrets, private data, or unfinished personal information on it, simply because it is not the main site. Test with realistic but safe data. Used well, previews and staging turn deployment from a risky leap into a series of small, checkable steps, and that calm is worth the small extra setup. Used well, previews and staging turn deployment into small, checkable steps.
Check: What is the difference between a preview deployment and a staging site?
Section 35 — Production versus staging versus development
Development, staging, and production are three environments for the same project, each with a different purpose, and confusing them is a common source of deployment mistakes. Development is your own computer, where you write code, experiment freely, and break things without consequence. Staging is a hosted copy that mimics production, where you test a near-final version before release. Production is the live site that real visitors use, where stability matters most and experiments do not belong. Keeping those environments distinct, in both setup and mindset, is what allows you to move fast in development without endangering production.
Each environment should have its own configuration. Development might point to test data, show detailed error messages, and load tools that help you debug. Production should point to live data, show friendly error messages that do not leak details, and load only what visitors need. Staging should match production's configuration as closely as possible, except where test data is deliberately used. Environment variables, discussed earlier, are the mechanism for these differences: the same code reads a different value in each environment. Hard-coding a development address into code and deploying it to production is a classic mistake, and it is entirely avoidable once you treat configuration as per-environment.
Data is another boundary to respect. Development and staging should use test data, not copies of real visitors' private information, unless you have a proper reason and proper protections. Testing with real personal data on a staging site that is less protected than production creates unnecessary risk. Similarly, you should not experiment with production data to see what happens; that is what staging and test data are for. If a bug only appears with production data, reproduce it safely with anonymised or synthetic data that captures the same pattern, rather than poking at the live site.
The workflow that ties the environments together is promotion: a change moves from development to staging for testing, and from staging to production only when it passes. That promotion should be deliberate, not accidental. A push to the wrong branch should not silently become a production deployment, which is why hosts let you choose which branch deploys to production and which branches create previews. Learn your host's branch settings, label your branches clearly, and check the deployment log after each promotion. When the environments are clear, deployment becomes a pipeline with gates, rather than a single leap from your computer to the world, and that structure protects both you and your visitors. When the environments are clear, deployment becomes a pipeline with gates, rather than a single leap from your computer to the world, and that structure protects both you and your visitors. Clear boundaries also make it easier for a new teammate to understand where to test and where never to experiment.
Check: Why should staging use test data rather than real visitors' private data?
Section 36 — Version control as the deployment source
Version control, most commonly with Git, is the system that records the history of your code, and it has become the normal source for deployment on modern hosts. Instead of uploading files by hand and hoping you remembered everything, you commit your changes to a repository, push that repository to a hosted service, and let the host deploy from a specific branch. That chain — commit, push, deploy — gives every live version a clear origin: you can see which commit produced it, who made it, when, and what changed. If a deployment goes wrong, you can trace it to a change, and if necessary, return to an earlier commit.
The benefits go beyond convenience. Version control protects you from losing work, because every committed change is stored with its history, and you can recover an earlier version even after a mistake. It also makes collaboration possible, because several people can work on different branches and merge their changes in a controlled way, rather than overwriting each other's uploads. For deployment, the most important benefit is repeatability: the host builds from the same repository you tested, not from a folder on one person's computer that may contain uncommitted experiments. That consistency removes a whole class of it-works-on-my-machine problems.
Good version control habits support good deployment habits. Commit small, focused changes with clear messages, such as Fix catalogue search on small screens, rather than vague messages like Updates. Keep secrets out of the repository, using an ignore file for configuration that contains credentials, and provide an example configuration file with placeholders instead. Do not commit built output unless your host specifically requires it; the host should build from source, so the repository stays clean and the build remains the single source of the deployed files. Review what you are about to push, especially before pushing to the branch that deploys to production, because that push may go live within minutes.
Finally, understand the relationship between branches and deployments on your host. Usually, one branch, often called main, deploys to production, while other branches create preview deployments. Pushing to a feature branch therefore does not disturb the live site, which frees you to experiment. Merging that branch into main is the deliberate act that promotes the change. If your host is set up differently, learn its rules before you push, and write them in your project notes. Version control is not just a backup system; it is the deployment source, the audit trail, and the safety net that makes frequent, confident updates possible. Version control is not just a backup system; it is the deployment source, the audit trail, and the safety net that makes frequent, confident updates possible for solo developers and teams alike.
Check: How does deploying from version control help you trace a bad deployment?
Section 37 — Continuous integration in plain language
Continuous integration, often shortened to CI, is the practice of merging code changes frequently and automatically checking them, rather than merging rarely and discovering problems late. In a solo project, CI may sound like overkill, but its core idea is simple and useful at any scale: every time you push a change, an automated system runs a set of checks — such as building the project and running tests — and reports whether the change passes. If it passes, you have confidence to deploy. If it fails, you learn about the problem immediately, while the change is still fresh in your mind, rather than weeks later when you have forgotten what you did.
The key word is continuous. Traditional workflows saved integration for the end of a project, when many changes were combined at once and conflicts and bugs arrived together, making them hard to untangle. Continuous integration reverses that: small changes are integrated often, so each integration is small and its problems are easy to find. Even for a solo developer, pushing a change and seeing an automated build succeed is a valuable confirmation that the project still works as a whole, not just on the part you touched. It also creates a habit of keeping the main branch in a working state, which makes deployment a routine step rather than a special event.
CI runs on a hosted runner, a temporary computer provided by a service, which checks out your code, installs dependencies, and runs the steps you configured. It does not run on your computer, which is the point: it proves the project builds from a clean copy, not only in your personal setup with its particular tools and cached files. If a build passes locally but fails in CI, that difference is information, not an annoyance. It usually reveals a missing dependency, a file that was never committed, or an assumption about your machine that does not hold elsewhere. Fixing that gap makes the project more portable for everyone, including your future self on a new computer.
You do not need a complex CI setup to benefit. A simple configuration that installs dependencies, builds the project, and runs any tests you have is enough to start. As your testing grows, CI grows with it, running more checks without you remembering to run them by hand. The next section walks through that simple pipeline step by step. For now, remember the idea: integrate often, check automatically, and fix failures while they are small. That discipline is what turns deployment from a nervous occasion into a calm, repeatable habit. That discipline turns deployment from a nervous occasion into a calm, repeatable habit. That discipline is what turns deployment into a calm habit.
Check: Why is it valuable that CI runs on a clean machine, not just on your computer?
Section 38 — A simple CI pipeline: install, build, test
A CI pipeline is a sequence of steps that runs automatically when you push code, and a simple pipeline has three stages: install, build, and test. Install means fetching the dependencies your project needs, such as libraries listed in its configuration, so the runner has everything required. Build means running the build step, if your project has one, to produce the finished files for the browser. Test means running any automated checks you have written, such as checking that functions behave as expected or that pages contain key elements. If any stage fails, the pipeline stops and reports the failure, and the change is not considered ready to deploy. If all stages pass, the pipeline reports success.
Each stage has a clear purpose, and understanding them helps you read a CI log without fear. Install fails usually mean a dependency cannot be found, a version is incompatible, or a configuration file is missing. Build fails usually mean a code error, a missing file, or a typo in an import that prevents the finished files from being produced. Test fails mean the code built, but something does not behave as expected, which is exactly what tests are for: catching behaviour problems before visitors do. Reading the log from the first failure, rather than scrolling to the end, will usually show you the root cause, because later errors are often consequences of the first.
Configuring a pipeline is less intimidating than it sounds. On many platforms, you add a small configuration file to your repository that names the steps, and the platform runs them on every push to specified branches. You do not need to write a long file for a first pipeline; a handful of lines that install, build, and test is enough. Keep the pipeline fast, especially at first, because a pipeline that takes a very long time discourages frequent pushes, which defeats the purpose of continuous integration. If a step is slow, ask whether it is essential for every push, or whether it belongs in a less frequent check.
A useful habit is to treat a failing pipeline as a normal, helpful signal, not as a judgement. It has caught a problem while it is cheap to fix, before deployment and before visitors encounter it. Fix the cause, push again, and watch the pipeline pass. Over time, that loop builds trust in the main branch: if the pipeline is green, the project builds and its tests pass, and deployment is a safe next step. If it is red, deployment should wait until the cause is understood and fixed. That simple rule — green means go, red means stop and fix — is the heart of a CI pipeline, however simple or sophisticated it becomes.
Check: What should you do when a CI pipeline fails, and what should you not do?
Section 39 — Continuous deployment and automatic publishing
Continuous deployment is the step beyond continuous integration: when a change passes its automated checks, it is automatically published to the live site, without a person manually pressing a deploy button each time. Continuous delivery is a closely related term, meaning the change is automatically prepared for release and could be deployed at any time, but a person still decides when to press the button. The difference is who makes the final decision — a machine or a human — and both are legitimate choices. For a small personal site, automatic publishing after a green pipeline feels effortless. For a client site or a site with a launch date, a human decision before release may be wiser.
Automatic publishing has clear advantages. It removes the delay between finishing a change and sharing it, it removes the risk of forgetting to deploy, and it ensures the live site always reflects the main branch. It also enforces discipline: because every push can go live, you learn to keep pushes small, to test before pushing, and to write clear commit messages. That discipline is valuable even if you later choose manual release, because it keeps the main branch in a releasable state. Many modern hosts implement automatic publishing by default when connected to a repository, which is why understanding branch settings matters: a push to the production branch is, in effect, a release decision.
Automatic publishing also has risks that must be managed. A mistake that passes automated checks — a typo in visible text, a broken link that no test covers, a design change that looks wrong on a phone — will go live just as efficiently as a good change. Automation checks what you told it to check; it does not judge taste, clarity, or completeness. That is why preview deployments, discussed earlier, pair so well with automatic publishing: a change is previewed and reviewed on its own address, merged only when it looks right, and then automatically published by the merge. The human judgement happens before the merge, and the machine handles the mechanics after it.
Whether you choose automatic or manual publishing, the verify step remains yours. After an automatic deployment, open the live site, check the pages that changed, and confirm the result in a private window. Set up notifications for deployment failures, so a broken build does not sit unnoticed. And know how to roll back, covered in a later section, because automatic publishing makes rollback skill more important, not less. Automation should make deployment boring and reliable, not thoughtless. When it is set up with previews, checks, and a clear rollback path, it frees you to focus on the site itself, confident that publishing will take care of itself.
Check: What is the difference between continuous deployment and continuous delivery?
Section 40 — Secrets and variables in CI
CI systems need configuration values, just as hosts do, and they handle secrets with special care because pipeline logs are often visible to collaborators. A CI secret is a value stored in the platform's settings, such as a token that allows deployment, which the pipeline can use without displaying it. A CI variable is a non-secret configuration value, such as a build setting, which the pipeline can read and which may appear in logs. The distinction matters: putting a secret where a variable belongs, or printing a secret in a log for debugging, can expose it to anyone with access to the pipeline history. Treat CI settings with the same caution as host settings.
The most important rule is that a CI secret must never be printed, echoed, or included in an error message. Good CI platforms automatically mask secret values in logs, replacing them with asterisks, but masking is a safety net, not a guarantee. Avoid commands that dump the environment, and avoid copying a secret into a test or a build output that might be published. If you suspect a secret has been exposed in a log, treat it as exposed: revoke it, create a new one, and update the CI settings. The cost of rotating a secret is small compared with the cost of leaving a compromised credential in place while hoping nobody noticed.
Secrets in CI are also where the front-end rule from earlier returns with full force: a secret used during a build can still end up in the built files if the build embeds it. A deployment token that the CI system uses to publish the site should stay on the runner and never be written into JavaScript. A public configuration value, by contrast, may be embedded safely, because it was never secret. Before adding any value to CI, ask two questions: who should be able to read this value, and will this value appear in the built output? If the answer to the first question is only the pipeline, and the answer to the second is yes, you have a design problem to solve before you proceed, usually by moving the secret to a server or a trusted service.
Finally, keep CI secrets organised and minimal. Give each secret a clear name that describes its purpose, grant it only the permissions it needs, and remove secrets for services you no longer use. Document, in private notes, which secrets exist and where they are used, without writing the values themselves into those notes. Rotate secrets periodically and whenever a collaborator leaves a project or a device is lost. Those habits, applied to a solo project, feel like extra work, but they build the muscle memory that larger projects require, and they ensure that automation, which is meant to make deployment safer, does not quietly become a new way to leak what you meant to protect.
Check: Why should a CI pipeline never print a secret value in its log?
Section 41 — When a deploy fails: reading the log
A failed deployment feels alarming, but it is usually a precise message in disguise. Every modern host and CI system produces a log, a chronological record of what it tried to do and where it stopped. Learning to read that log calmly is one of the most valuable deployment skills, because it turns a vague sense that something is broken into a specific file, line, or missing item. The log is not a judgement on your ability; it is a diagnostic tool, and it is almost always more helpful than guessing or redeploying the same code in hope.
Start at the first error, not the last. Logs often contain many lines after a failure, as later steps fail because an earlier step did not complete, and those later messages can mislead you. Scroll to the first line marked as an error or failure, and read it slowly. It will usually name a file, a command, or a missing dependency. Common first errors include a file that cannot be found, because it was never committed or its name is misspelled; a dependency that cannot be installed, because it is missing from the configuration or its version is unavailable; and a syntax error, because a typo prevents the code from being understood. Each of those has a straightforward fix, once you know which one it is.
Next, reproduce the failure locally if you can. Run the same build command on your computer and see whether it fails in the same way. If it does, you can fix and test rapidly without waiting for another deployment. If it passes locally but fails on the host, the difference is informative: a file that exists on your computer but was never committed, a dependency that exists in your local cache but is not listed in the configuration, or an environment variable that exists locally but not on the host. Those three differences account for a large share of deploy-only failures, and checking them in order will resolve most cases without changing your code's logic.
Finally, record what you learned. Note the error, its cause, and its fix in your project notes, in plain language, so the next time it appears you recognise it instantly. If the log's wording was confusing, note what it actually meant, in your own words. Over time, that personal glossary of deployment errors becomes a powerful resource, and failures that once took an hour take minutes. A failed deploy is not a wasted deploy if it teaches you something about your project, and a developer who reads logs methodically will always recover faster than one who redeploys blindly and hopes. A failed deploy is not wasted if it teaches you something about your project.
Check: Why should you start reading a deployment log at the first error, not the last?
Section 42 — Rollbacks: undoing a bad deploy
A rollback is the act of returning a live site to a previous, known-good version after a new deployment causes a problem. It is the safety net that makes frequent deployment tolerable, because it means a mistake is not permanent. Without a rollback plan, a bad deployment leaves you scrambling to fix the problem under pressure, while visitors see the broken version. With a rollback plan, you restore the previous version in minutes, calm the situation, and then fix the problem properly, without an audience watching you debug. Every deployment system you use should offer a clear rollback path, and you should know how to use it before you need it.
On modern hosts, rollback is often as simple as selecting an earlier deployment from a list and promoting it to live. Because each deployment is tied to a commit and stored by the host, returning to it does not require rebuilding or re-uploading files by hand. On hosts without that feature, rollback means redeploying the previous version from your repository, by checking out the earlier commit and pushing it, or by uploading the previous output folder. Either way, the principle is the same: the previous version must still exist somewhere you can reach it quickly. That is why version control and complete deployments matter: they preserve the versions you may need to return to.
A good rollback habit has three parts. First, know the steps before a crisis, by reading your host's documentation and, if possible, practising a rollback on a test site. Second, decide in advance what counts as a rollback-worthy problem: a page that fails to load, a form that stops working, a serious display error on a main page, or a security issue are all candidates, while a minor typo can usually wait for a forward fix. Third, after rolling back, verify that the live site is indeed the old version, using a private window, and tell anyone affected that the problem is contained. Only then should you investigate the cause, fix it on a branch, test it on a preview, and deploy it again through the normal route.
Rollback is not an admission of failure; it is a professional response to a normal event. Even experienced teams deploy problems, because no amount of testing catches everything. What distinguishes them is not that they never need to roll back, but that they can do so quickly, calmly, and without making the situation worse. Practise the steps, keep previous versions available, and treat rollback as part of deployment, not as an emergency improvisation. A site with a known rollback path is a site you can improve boldly, because you know you can step back safely. Practise it before you need it.
Check: Why is a quick rollback better than fixing a bad deploy while visitors see the broken version?
Section 43 — Monitoring a live site
Monitoring is the practice of watching a live site after deployment, so you learn about problems before visitors have to report them, or at least promptly when they do. A site that is deployed and forgotten is a site that can break silently: a host outage, an expired certificate, a broken link introduced by an external change, or a form that stops delivering can all go unnoticed for days if nobody is watching. Monitoring does not need to be elaborate for a small site, but it does need to be regular and honest. A simple, consistent check beats an ambitious system that nobody actually looks at.
The simplest form of monitoring is a routine you perform yourself: open the live site regularly, click through key pages, submit a test form occasionally, and check that HTTPS still works and that the site loads promptly. That routine catches many problems, but it depends on you remembering, and it misses outages that happen between checks. Automated monitoring improves on it by checking the site at intervals and alerting you when it fails to respond, returns an error, or takes unusually long. Many hosts and free services offer basic uptime checks, which request your home page periodically and notify you by email if it stops responding. For a small site, that single check is a strong starting point.
Beyond uptime, consider what else deserves watching. If your site has a form, check periodically that submissions still arrive. If it depends on an external service, such as a data feed or a map, notice when that service changes or fails, because your site may break through no fault of your own. If it uses analytics, look occasionally at traffic patterns, not to obsess over numbers, but to spot a sudden drop that might indicate a broken page or a lost search ranking. Logs from your host can also reveal errors, such as frequent 404s for a particular path, which may indicate a broken link that many visitors are following.
Monitoring is also about response, not just detection. Decide in advance what you will do when an alert arrives: check the live site in a private window, check the host's status page, read the deployment log if the outage followed a change, and roll back if the change caused it. Keep contact details for your host and registrar in your private notes, so you are not searching for them during an outage. A monitored site is not a site that never fails; it is a site whose failures are noticed quickly, understood calmly, and fixed with a clear process, which is the best promise a developer can make to visitors. A monitored site is one whose failures are noticed quickly and fixed calmly.
Check: What is the simplest automated check that can alert you when a site stops responding?
Section 44 — Uptime, errors and user reports
Uptime is the proportion of time a site is available and responding correctly, and it is a useful but limited measure of reliability. A site with high uptime is available most of the time, but uptime alone does not tell you whether the site is usable: a home page that loads while a form silently fails still counts as up, even though visitors cannot complete their task. That is why uptime should be paired with error tracking and attention to user reports. Together, they answer three different questions: is the site reachable, is it working correctly, and are visitors actually succeeding?
Errors come in forms you can observe without waiting for complaints. Server logs and host dashboards may show how often pages return 404 or 500 statuses, which paths fail most, and whether errors cluster after a deployment. Browser errors, visible in developer tools during testing, may reveal scripts that fail on certain devices. A sudden rise in 404s for one path often means a link changed or a page moved without a redirect. A rise in 500s often means a server-side component failed, which for a static site may point to a form service or a function rather than the static files themselves. Watching those patterns, even informally, lets you fix systemic problems before they affect many visitors.
User reports are the third source, and they deserve respect even when they are vague. A visitor who says the site does not work may be experiencing a problem you cannot reproduce on your device, because of a different browser, connection, or screen size. Ask, politely, for the details that help you reproduce it: what page, what device and browser, what they were trying to do, and what they saw, including any error message. Thank them, even if the problem turns out to be on their side, because reporting takes effort and most visitors simply leave silently. Fix the cause when you can, and reply to let them know, because that follow-through turns a frustrated visitor into a loyal one.
Finally, keep perspective on reliability. A small personal site does not need the same uptime guarantees as a bank, and chasing perfection can consume time better spent on content and usability. Aim for a site that is available, that you check regularly, whose errors you notice, and whose visitors feel heard when they report a problem. Document recurring issues and their fixes, so patterns become visible over time. Reliability, like deployment itself, is a habit of attention, not a single achievement, and it grows stronger with each problem you notice, understand, and fix. Reliability, like deployment itself, is a habit of attention, not a single achievement, and it grows stronger with each problem you notice, understand, and fix.
Check: Why is uptime alone not enough to tell you whether a site is working well?
Section 45 — Search engines after launch: sitemaps and robots
After launch, you want search engines to find, understand, and show your site to people searching for its content, and two small files help with that: a sitemap and a robots file. A sitemap is a list of your site's pages, usually in a structured format, that tells search engines which pages exist and which are most important. A robots file, named robots.txt, tells search engine crawlers which parts of your site they may visit and which they should avoid, such as preview areas or private pages. Neither file guarantees ranking, but both help crawlers work efficiently, especially on a new site that has few incoming links.
Creating a sitemap for a small static site is straightforward. Many build tools and generators can produce one automatically from your pages, or you can write a simple list by hand for a site with few pages. The sitemap should include the canonical address of each public page you want indexed, and it should be kept up to date when you add or remove pages. An out-of-date sitemap that lists deleted pages or omits new ones is worse than no sitemap, because it misleads the crawler. Place the sitemap at a standard location, such as /sitemap.xml, and reference it in your robots file, so crawlers can find it without guessing. For a site with many pages, a sitemap index that points to several sitemaps may be used, but that is beyond a first launch.
The robots file requires care, because a mistake can hide your whole site. A robots file that disallows all crawling will prevent search engines from indexing your pages, which is appropriate for a staging site but disastrous for a live site you want found. Before launch, check your robots file explicitly: it should allow crawling of public pages and disallow only what you genuinely want hidden, such as an admin area or a preview folder. Do not rely on a robots file for privacy or security, because it is a public request, not a barrier; anyone can read it, and a malicious crawler can ignore it. Truly private content must be protected by authentication, not by a robots instruction.
After creating both files, submit your site to search engines' webmaster tools if you use them, and check that the sitemap is recognised and that pages are being indexed over time. Indexing takes time, especially for a new site, and patience is required; do not expect immediate ranking. Focus on clear titles, descriptive headings, and genuinely useful content, because those are what search engines ultimately reward. Sitemaps and robots files are the signposts that help crawlers find that content, and setting them up correctly is a small, professional step that completes a launch.
Check: Why is a robots file not a suitable way to protect truly private content?
Section 46 — Analytics without slowing the site
Analytics is the practice of measuring how visitors use a site: which pages they visit, where they come from, how long they stay, and which actions they complete. Done well, it answers practical questions, such as whether a new guide is being read, whether visitors find a contact page, or whether a page is being abandoned quickly. Done badly, it slows the site, invades privacy, and produces numbers nobody acts on. The front-end developer's job is to set up analytics in a way that is light, honest, and useful, and to respect visitors while learning from them.
The first decision is what to measure, and the answer should be as small as possible. For most small sites, a handful of measures suffices: page views for key pages, the source of visits in broad terms, and completions of a key action, such as submitting a form or downloading a guide. Measuring everything, including every click and scroll, creates noise and privacy concerns without improving decisions. Before adding any tracking, write down the question you hope it will answer and the decision it will inform. If you cannot name a decision, do not track that thing. That discipline keeps analytics focused and keeps the site fast, because every tracking script adds download and execution cost.
Privacy is the second decision, and it is not optional. Tell visitors, in plain language, what you collect and why, usually in a privacy page, and choose a tool that respects visitor choices, such as honouring do-not-track signals or offering cookieless measurement where available. Avoid collecting personal data you do not need, such as precise location or individual browsing histories, and never use analytics to identify individual visitors without a clear, lawful reason and consent. Many modern analytics tools offer privacy-friendly modes that aggregate data without personal tracking, and those are often the right choice for a small site. Trust is part of analytics: visitors who feel watched will leave, and their departure will itself distort your numbers.
Technically, keep analytics light. Load the tracking script in a way that does not block the page's first display, and test the site's speed with and without it. If analytics noticeably slows the site, reconsider the tool or its configuration. Review the data regularly, but not obsessively, and act on what you learn: if a page is rarely visited, improve its title or its links; if a form is often abandoned, simplify it. Analytics should lead to better content and clearer navigation, not to dashboards admired for their own sake. A small site with a few honest measures, reviewed monthly and acted upon, learns more than a large site drowning in numbers nobody reads. A few honest measures, reviewed monthly, teach more than dashboards nobody reads.
Check: Before adding a tracking measure, what question should you ask yourself?
Section 47 — Accessibility and legal pages on a live site
A live site has responsibilities that a private practice project does not, and two of them are accessibility and basic legal pages. Accessibility means the site can be used by people with different abilities, including those who use screen readers, keyboard navigation, or high-contrast settings. Legal pages mean the small set of pages that explain, in plain language, who runs the site, how personal data is handled, and what terms apply. Both are part of launching professionally, not optional extras to add if time remains, because they affect real visitors from the first day the site is public.
Accessibility on a live site is mostly a continuation of good front-end practice, applied consistently. Check that every page can be navigated by keyboard alone, that focus is visible, that images have meaningful descriptions, that headings follow a logical order, and that colour is never the only way information is conveyed. Test with a screen reader if you can, even briefly, because that experience reveals problems that visual checking misses. Also check contrast, text size, and touch target size on a phone, because many visitors will use the site in conditions very different from your desk. Accessibility failures on a live site are not theoretical; they exclude real people, and they are often simple to fix once noticed.
Legal pages depend on your location, your audience, and what your site does, so you should not copy another site's pages word for word. At a minimum, many sites need a privacy notice explaining what data, if any, is collected, through forms, analytics, or cookies, and what is done with it. A site that sells, takes bookings, or handles accounts needs terms that explain the service and the visitor's rights. A site that uses cookies for analytics or advertising may need a cookie notice, depending on its audience's jurisdiction. If you are unsure what applies to your site, seek guidance appropriate to your situation rather than guessing, and keep the language plain: a legal page that nobody can understand fails its purpose, even if it looks formal.
Finally, make these pages easy to find. Link to privacy and terms pages from the footer of every page, so a visitor can reach them from anywhere, and keep them up to date when the site changes, for example when you add a new form or a new analytics tool. An out-of-date privacy page that describes a tool you no longer use, or omits one you now use, misleads visitors. Treat accessibility and legal pages as living parts of the site, reviewed at each significant launch, not as one-time paperwork. A site that is accessible and honest about its data practices earns trust, and trust is the foundation on which repeat visits are built.
Check: Why should legal pages be kept up to date when a site adds a new form or tool?
Section 48 — A pre-launch checklist
A pre-launch checklist is a written list of checks you run before a site goes live, and it exists because memory alone is unreliable under launch pressure. When you are excited or rushed, it is easy to forget a broken link, an untested form, or a missing page, and each of those becomes a public problem within minutes of launch. A checklist turns launch from a feat of memory into a methodical process: work through the items, fix what fails, and only then announce the site. It does not need to be long, but it does need to be written down, used every time, and updated when you learn from a mistake.
A useful checklist covers content, function, and presentation. Content checks include proofreading every page, confirming titles and descriptions are present and accurate, checking that images have descriptions, and removing placeholder text and test data. Function checks include clicking every link, submitting every form with a test entry, testing navigation on a phone and in a second browser, and confirming that search and filtering, if any, work correctly. Presentation checks include confirming the site looks correct at common screen sizes, that text is readable, that focus is visible for keyboard users, and that the site loads promptly on a realistic connection. Technical checks include confirming HTTPS works on all addresses, that the custom 404 page appears for a wrong address, that redirects work, and that analytics, if used, is recording without slowing the site.
Also include deployment-specific checks that beginners often forget. Confirm that the deployed folder is the correct output folder, that no secrets are present in the deployed files, that the robots file allows crawling of public pages, and that the sitemap lists current pages. Confirm that preview and staging addresses are not the ones being promoted, and that old test pages are not still publicly linked. Check the site in a private window, so cached files do not hide a problem, and ask a second person to click through it if possible, because a fresh pair of eyes catches what familiarity hides. Each of these checks takes a minute or less, and together they prevent most launch embarrassments.
Keep your checklist in your project notes and refine it after each launch. When a problem slips through, add a check that would have caught it, in plain language, so the same mistake does not recur. Over time, the checklist becomes a personal launch standard, and launches become calmer and more predictable. A checklist is not bureaucracy; it is a kindness to your future self and to your visitors, ensuring that the site you announce is the site you actually built. A checklist is a kindness to your future self and to your visitors.
Check: Why is a written checklist more reliable than memory at launch time?
Section 49 — Launch day: a calm sequence
Launch day should feel calm, not chaotic, and that calm comes from doing things in a sensible order rather than all at once. A good sequence starts the day before, or at least hours before announcement, with a final deployment to production and a full verification pass. Deploy, then open the live site in a private window, click through every main page, test every form, check HTTPS, and confirm the custom 404 page and redirects. Fix any problems now, while the audience is still small, and redeploy if needed, verifying again after each fix. Only when the live site passes that pass should you begin telling people about it.
The next step is to announce in stages, rather than to everyone at once. Share the link first with a small group — a friend, a teacher, a colleague — and ask them to open it on their devices and report anything odd. That small test often catches a device-specific problem, a slow image, or a confusing heading that you missed. Fix what they find, verify again, and then share more widely, through the channels your audience actually uses. Staged announcement is not timidity; it is a way of learning from real visitors while the audience is still manageable, so that by the time many people arrive, the site is already proven.
On launch day itself, keep your tools ready. Have your host dashboard, domain notes, and deployment log within reach, and know how to roll back if a serious problem appears. Monitor the site periodically, check that forms still deliver, and watch for messages from early visitors. Respond promptly and graciously to reports, even when they point out mistakes, because early visitors who feel heard often become the site's first advocates. Do not make large, untested changes on launch day in response to every suggestion; note suggestions, fix genuine breakages promptly, and schedule improvements for the following days, when you can test them properly.
Finally, record the launch. Note the date, the host, the domain, the commit or version deployed, and any problems found and fixed. That record turns a launch from a vague memory into a reference point for future updates, and it helps you answer questions later, such as when a feature was added or when a problem first appeared. Then celebrate, briefly and properly: launching a site that real people can use is a genuine achievement. A calm launch day is not an accident; it is the result of a checklist, a staged announcement, and a willingness to verify before proclaiming, and it sets the tone for how you will maintain the site afterwards. A calm launch sets the tone for how you will maintain the site afterwards.
Check: Why should you announce a launch in stages rather than to everyone at once?
Section 50 — After launch: updates without drama
After launch, a site enters its longest phase: maintenance, where small updates, fixes, and improvements arrive over weeks and months. The goal of this phase is to keep the site fresh and reliable without drama, which means treating every update with the same care as the launch, scaled to its size. A typo fix still deserves a preview and a live check, even though it takes only minutes. A new page still deserves proofreading, link checking, and a check on a phone. The discipline that made launch calm is the discipline that keeps a live site trustworthy over time, and abandoning it after launch is how small sites quietly decay.
A sensible update routine has a few steps. First, make the change on a branch or in a separate copy, not directly on the live site, so you can test it without affecting visitors. Second, preview it, either through a preview deployment or a local production preview, and click through the changed pages and any pages that might be affected. Third, check for side effects: did a stylesheet change alter another page, did a renamed file break a link, did a new image slow a page? Fourth, deploy through the normal route, whether automatic or manual, and verify live in a private window. Fifth, note the change in your project records, so you can trace it later. That routine takes minutes for a small change and prevents the majority of update-related breakages.
Content freshness also matters. Review the site periodically for out-of-date information, broken external links, and pages that no longer reflect what you offer. External sites change, move, or disappear, and a link that worked at launch may fail a year later. A regular link check, even a manual one every few months, keeps the site feeling maintained. Similarly, update the sitemap when you add or remove pages, update legal pages when you add a form or a tool, and refresh images or examples that have become stale. A site that is visibly maintained earns repeat visits; a site frozen at launch slowly loses relevance, even if its code still works.
Finally, plan for the site's future, including its eventual retirement or move. Keep your domain renewal and host details in your notes, keep the source repository up to date, and keep a backup of the project outside any single service. If you decide to move hosts, plan the move with the DNS patience described earlier, and keep redirects from old addresses. If you decide to close a site, leave a clear notice rather than letting it vanish silently, and consider redirecting its main address to a relevant page. A site's life after launch is not an afterthought; it is where most of its value is created, through steady, drama-free updates that respect the visitors who return.
Check: Why should even a small typo fix be previewed and checked live?
Practical task
Deploy a small three-page static site to a free host of your choice, connect or note a custom domain plan if you have one, and complete the full verify pass: home page, links, forms or placeholders, HTTPS, custom 404 page, and a private-window check on a phone or a second browser. Write a one-page launch note recording the host, the publish folder, the live address, the checks you ran, and any problem you found and fixed. Do not publish secrets or private data on the live site, and keep your launch note private if it contains account details.
Chapter questions
- Explain, in your own words, the difference between building, hosting, and publishing a site.
- A visitor reports seeing an old version of your site after you deployed a fix. List the caches you would check, in order, and what each check would tell you.
- Your domain's www address works but the bare domain does not. Describe the DNS and redirect checks you would run, in order.
- A teammate proposes putting a private API key directly into front-end JavaScript because it is faster. Explain why this is unsafe and what safer alternative you would propose.
- Describe a complete CI pipeline for a small static site, including what should happen when a stage fails.