Skip to content

Web Foundations and Front-End Roles

Step 1 of 45

Browsers, HTTP, and the Developer Workflow

Introduction

This is the first lesson of the course and it maps to course 1 of the Meta Front-End Developer pathway, Introduction to Front-End Development. Before you write a single line of React, you need a clear mental model of what happens between typing a web address and seeing a page, and you need a development environment that anyone on your team can reproduce. Most beginner bugs, "my CSS does not load", "the page is blank", "it works on my machine", are not React bugs at all. They are request, path, or tooling bugs.

Throughout the course we build one original project, Harbor Workshops: a responsive catalog and booking interface for community workshops such as pottery, bike repair, and bread baking. All briefs, code, and tests in this course are original OnLevelUp material. This lesson prepares the ground for that project.

By the end you will be able to describe the client/server model, read an HTTP exchange in the browser's developer tools, set up a reproducible Node-based project, and diagnose the most common "resource did not load" failure.

Learning objectives

After this lesson you can:

  1. Explain the responsibilities of front-end, back-end, and full-stack developers.
  2. Break a URL into its parts and describe what a browser does with it.
  3. Read an HTTP request and response, including method, status code, and headers.
  4. Use the Network, Console, and Elements panels of browser developer tools to find a problem.
  5. Install Node.js, create a project with npm, and explain what package.json and package-lock.json do.
  6. Distinguish a build tool (Vite) from a UI library (React).

1. Who does what: front end, back end, full stack

A website is a conversation between two programs. The client is the browser running on the visitor's device. The server is a program on another machine that answers requests. The role you hold depends on which side of that conversation you build.

Role Works on Typical technologies Example task for Harbor Workshops
Front-end developer What runs in the browser: structure, appearance, interaction HTML, CSS, JavaScript, React Build the workshop card grid and the booking form
Back-end developer Servers, databases, business rules, security Node.js, Python, SQL, REST APIs Store bookings and refuse a booking when a workshop is full
Full-stack developer Both sides A mix of the above Build the form and the endpoint that receives it

A front-end developer does not only "make it pretty". Typical responsibilities include semantic structure, accessibility, responsive layout, state management, calling APIs, testing, and performance. Notice that the browser runs code that the user controls. Anything in front-end code is visible to the visitor, so a front-end developer never stores secrets such as API keys in it and never relies on front-end checks alone for security. Validation in the browser improves the experience, but the server must validate again.

Concrete example. A visitor clicks "Reserve" on a bread-baking class that has one seat left. The front end disables the button and shows "Reserving…". The back end checks seat availability inside a database transaction. If two people click at the same moment, only the back end can decide who gets the seat. The front end's job is to display the outcome honestly, either a confirmation or "Sorry, this class just filled up".

2. From URL to pixels

Anatomy of a URL

Consider this address:

https://harbor.example/workshops/pottery?level=beginner&sort=date#reviews
Part Value Meaning
Scheme (protocol) https How to talk to the server; HTTPS encrypts the traffic
Host harbor.example Which server (found through DNS)
Port not shown (443 for HTTPS, 80 for HTTP) Which door on the server
Path /workshops/pottery Which resource
Query string ?level=beginner&sort=date Extra parameters, key=value pairs separated by &
Fragment #reviews A position inside the page; never sent to the server

The fragment detail matters. The browser removes #reviews before making the request and uses it afterwards to scroll to the element with id="reviews". This is why single-page applications can change the fragment without triggering a server request.

What the browser does

  1. Parse the URL and decide what to request.
  2. Resolve the host through DNS to an IP address.
  3. Open a connection (and for HTTPS, negotiate encryption).
  4. Send an HTTP request.
  5. Receive the response, normally an HTML document.
  6. Parse the HTML into the DOM (Document Object Model), a tree of objects representing the page.
  7. Discover more resources (stylesheets, scripts, images) and request each one.
  8. Apply CSS to compute styles, lay out the elements, and paint pixels.
  9. Run JavaScript, which may change the DOM and trigger layout and paint again.

The key insight: the first response is only the beginning. A page with one HTML file, one CSS file, one script, and six images triggers at least nine requests. If any one fails, the page may look broken even though the HTML arrived.

3. HTTP in practice

HTTP is a request/response protocol. The client sends a request; the server sends exactly one response.

A request

GET /workshops/pottery HTTP/1.1
Host: harbor.example
Accept: text/html
  • The method says what to do. GET retrieves, POST creates or submits, PUT or PATCH updates, DELETE removes.
  • The path names the resource.
  • Headers carry metadata such as the host, accepted formats, and cookies.
  • A request may have a body, for example JSON in a POST.

A response

HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Cache-Control: max-age=300

<!doctype html>
<html lang="en">...

The status code tells the client how things went. Learn the families:

Range Meaning Common examples
1xx Informational 101 Switching Protocols
2xx Success 200 OK, 201 Created, 204 No Content
3xx Redirection 301 Moved Permanently, 302 Found, 304 Not Modified
4xx Client error 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests
5xx Server error 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable

The most useful single habit in front-end debugging is reading the status code first. A 404 means "the server does not know this path", usually a typo or a wrong relative path. A 403 means "I know it, but you may not have it". A 500 means the server crashed, and no amount of editing front-end code will fix it.

The Content-Type header tells the browser how to treat the body. A stylesheet served as text/html (for example, because the server returned an error page instead of the CSS file) will not be applied. Developer tools show this mismatch clearly.

Worked example 1: reading an exchange

Open the Harbor page, open the Network panel, and reload. You see these rows:

Name Status Type Size
pottery 200 document 4.1 kB
styles.css 404 text/html 0.3 kB
app.js 200 script 12 kB
kiln.jpg 200 jpeg 180 kB

Reasoning, step by step.

  1. The document loaded (200), so the HTML is not the problem.
  2. styles.css returned 404, and its type is text/html: the server answered with its "not found" page instead of CSS. That explains why the page appears unstyled.
  3. The script and the image are fine, so the page works but looks plain.
  4. Click styles.css, look at the Request URL: https://harbor.example/workshops/css/styles.css. The HTML says <link rel="stylesheet" href="css/styles.css">, a relative path resolved against /workshops/.
  5. The file actually lives at /css/styles.css. Fix: use a root-relative path href="/css/styles.css".

Why not the alternatives? Rewriting the CSS would change nothing, because the file never arrives. Clearing the cache would not help either: a 404 is not a stale-cache symptom. Reading the Network panel first saved the time.

4. Developer tools: your instruments

Every major browser ships with developer tools (open with F12 or Ctrl/Cmd + Shift + I). Learn four panels.

Panel Use it to Typical question it answers
Elements Inspect the live DOM and applied CSS rules "Why is this button blue and not green?"
Console See errors and warnings, run JavaScript "What did the script complain about?"
Network See every request, status, timing, headers "Did the file load? How big was it?"
Application (or Storage) Inspect cookies, local storage "What did the app save?"

Two details worth practicing. First, the Elements panel shows the DOM after JavaScript, which can differ from "view source". Second, a red entry in the Console includes a file and line number you can click.

console.log("booking count:", 3);
console.table([{ name: "Pottery", seats: 2 }, { name: "Bread", seats: 0 }]);

The first line prints booking count: 3. The second prints a readable table with the columns name and seats. console.table is a quick way to inspect arrays of objects.

Exam tip. When a question describes a symptom ("the page is unstyled", "the image is missing"), decide which panel gives the fastest evidence. Missing resources point to Network; script errors point to Console; wrong styles point to Elements.

5. The developer workflow: editor, terminal, Node, npm

The tools

  • A code editor such as Visual Studio Code gives syntax highlighting, search, and extensions.
  • A terminal lets you run commands. You will use it every day; lesson 3.1 covers it in depth.
  • Node.js runs JavaScript outside the browser. We use it to run development servers, build tools, and tests. Always install a currently supported long-term-support (LTS) release, and check the Node.js website for which versions are supported when you read this.
  • npm is Node's package manager. It downloads libraries (packages) and runs scripts.

Check your installation:

node --version
npm --version

Each prints a version number such as v22.x.x or 10.x.x. If the command is "not found", the installer did not add Node to your PATH; reopen the terminal or reinstall.

Creating a reproducible project

A reproducible project is one that a teammate can clone and run with the same result. Two files make this possible.

  • package.json lists the project name, scripts, and the packages it requires, using version ranges.
  • package-lock.json records the exact versions that were installed. Commit it to Git. npm ci installs exactly what the lockfile says and is the right command in automated builds; npm install may update the lockfile.

Create a minimal project:

mkdir harbor-workshops
cd harbor-workshops
npm init -y

npm init -y writes a package.json with default values. Edit it so it contains a script:

{
  "name": "harbor-workshops",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "scripts": {
    "greet": "node greet.js"
  }
}

Create greet.js:

const workshops = ["Pottery", "Bread baking", "Bike repair"];
console.log(`Harbor offers ${workshops.length} workshops: ${workshops.join(", ")}`);

Run npm run greet. Predicted output:

Harbor offers 3 workshops: Pottery, Bread baking, Bike repair

"private": true prevents accidental publication to the npm registry. "type": "module" makes .js files use modern import syntax, which we use heavily later.

Dependencies and devDependencies

npm install react react-dom
npm install --save-dev vite

Packages needed when the app runs go in dependencies. Tools needed only to build or test go in devDependencies. The node_modules folder holds the downloaded code; it can be huge and is regenerated from the lockfile, so you never commit it. A .gitignore file containing node_modules keeps it out of Git.

Semantic versioning

A version 1.4.2 is MAJOR.MINOR.PATCH. In a range, ^1.4.2 allows 1.x.y updates at or above 1.4.2, while ~1.4.2 allows only 1.4.x. Major versions can break your code, which is why you read release notes before upgrading across one.

6. Tooling is not React

Beginners often say "I installed React" when they mean "I created a project with a toolchain". Separate the two ideas.

Concept What it is Example
UI library Code your app imports to describe interfaces React
Build tool / dev server Compiles, bundles, and serves your code during development Vite
Test runner Runs your tests Jest
Package manager Installs and records dependencies npm

Why do we need a build tool? Browsers understand HTML, CSS, and JavaScript. React code uses JSX, a syntax extension that browsers cannot run directly. A build tool transforms JSX into plain JavaScript, bundles many files into a few, and provides a development server with fast reloading.

Today the maintainers of React recommend starting new projects with a framework or a modern build tool such as Vite; the older Create React App is deprecated and should not be your default for new projects. Always confirm current recommendations on the official React documentation at react.dev when you start a project, because tooling evolves faster than courses do.

A Vite project starts like this:

npm create vite@latest harbor-app -- --template react
cd harbor-app
npm install
npm run dev

Vite prints a local address such as http://localhost:5173/. Open it, edit a file, save, and the browser updates without a manual reload. The structure includes:

harbor-app/
  index.html        # the single HTML page
  package.json
  src/
    main.jsx        # entry point that mounts React
    App.jsx         # first component
  public/           # files served as-is

Concrete example of why the distinction matters. A teammate's build fails with "Cannot find module 'vite'". That is a tooling problem: dependencies were not installed. Running npm ci fixes it. Rewriting React components would be wasted effort.

Environment variables: a warning

Front-end build tools can inject environment variables into the browser bundle. Anything injected becomes public. Never put a database password or a private API key in front-end code. Only values safe for anyone to read, such as a public API base URL, belong there.

7. Common pitfalls

  • Opening the HTML file with a double-click (file:// URL). Some features, such as module scripts and fetch, behave differently or are blocked. Use a dev server.
  • Case sensitivity. Styles.css and styles.css are different files on most servers even if they match on your laptop.
  • Relative versus root-relative paths. css/a.css, ./css/a.css, ../css/a.css, and /css/a.css resolve differently.
  • Trusting the cache. If an edit has no effect, a hard reload or disabling cache in the Network panel rules out stale files.
  • Committing node_modules or secrets.
  • Confusing a 404 from the API with a 404 for the page. Check the Request URL.

Exam tips

  • Memorize the status code families and the five or six codes you meet daily.
  • Know that the fragment is not sent to the server.
  • "Which tool shows whether a stylesheet loaded?" is a Network question; "which shows the computed width?" is Elements.
  • A library and a build tool are different things, and npm ci follows the lockfile exactly.

Mini case study: the vanishing stylesheet

Situation. The Harbor team deploys the site to a staging server. The home page looks fine, but /workshops/pottery appears with plain black text on white. On the developer's laptop everything looks right. The page's <head> contains <link rel="stylesheet" href="styles/main.css">. The Network panel on staging shows styles/main.css with status 404 for the pottery page, while the home page loads styles/main.css with 200.

Questions.

  1. Why does the same href succeed on one page and fail on another?
  2. What is the minimal fix?
  3. Which evidence would confirm the fix?

Solution.

  1. The path styles/main.css is relative to the current URL's directory. On / it resolves to /styles/main.css, which exists. On /workshops/pottery it resolves to /workshops/styles/main.css, which does not. The laptop worked because the developer opened a flat folder where every page sat next to styles/.
  2. Change the link to a root-relative path: href="/styles/main.css", so it resolves identically on every page. (Setting a <base> element is possible but easy to misuse.)
  3. Reload with the Network panel open: the row now shows /styles/main.css, status 200, type text/css, and the Elements panel shows rules applied to the body.

Why other fixes are worse: copying the CSS file into /workshops/styles/ duplicates files and breaks again for /workshops/pottery/photos; inlining all CSS in every page removes caching.

Key terms

  • Client / server: the requesting program (browser) and the program answering.
  • URL: address of a resource: scheme, host, port, path, query, fragment.
  • HTTP: the request/response protocol of the web; HTTPS adds encryption.
  • Status code: three-digit result of a request.
  • DOM: tree of objects the browser builds from HTML.
  • Developer tools: browser panels for inspecting and debugging.
  • Node.js / npm: JavaScript runtime outside the browser / its package manager.
  • package.json / lockfile: declared dependencies / exact installed versions.
  • Vite: a build tool and dev server. React: a UI library.

Summary checklist

  • I can state what a front-end, back-end, and full-stack developer own.
  • I can split a URL into scheme, host, path, query, and fragment.
  • I can read a status code and name its family.
  • I can use Network, Console, and Elements to locate a problem.
  • I can run node --version, npm init -y, and npm run <script>.
  • I know why package-lock.json is committed and node_modules is not.
  • I can explain why Vite and React are different tools.

Official sources