π What Is Routing?
Routing is the logic your server uses to send a different response depending on which URL was requested.
The Problem (Before Routing)
π Currently, no matter what URL is visited (
/,/product,/anything), the server always sends back the same response.π We need the server to behave differently depending on the requested path β e.g.:
π
/overviewβ show an Overview pageπ¦
/productβ show a Product page
Note: In large real-world applications, routing gets very complex, so tools like Express are used to handle it (covered later in the course). For now, we're learning to build routing from scratch using plain Node.js.
π¨ Step 1: Inspecting the Request URL
Every request has a .url property containing the requested path:
console.log(req.url);
After restarting the server and reloading the browser, you'll notice two logs appear for a single page visit:
The actual path (e.g.,
/)/favicon.ico

π€ Why Two Requests?

π Browsers automatically send a separate request for the site's favicon (the small icon shown in browser tabs).
π« Since we don't have a favicon set up, this request can simply be ignored.
π§© Step 2: Understanding the url Module
π¦ Node has a built-in
urlmodule for parsing complex URLs β especially ones with query parameters, like:/product?id=23&something=elseποΈ The
urlmodule can convert these parameters into a clean, structured object.β³ Not needed yet for simple routes like
/overviewor/productβ it will be used later for more complex URLs.
π Step 3: Implementing Basic Routing with If/Else
Save the URL Path
const pathName = req.url;
Basic Routing Logic
if (pathName === '/overview' || pathName === '/') {
res.end('This is the OVERVIEW');
} else if (pathName === '/product') {
res.end('This is the PRODUCT');
} else {
res.end('<h1>Page not found!</h1>');
}
Explanation
π
pathName === '/overview' || pathName === '/'β Both the root URL (/) and/overviewshow the same Overview page.π¦
pathName === '/product'β Shows the Product page.π«
elseβ Handles any URL that doesn't match a defined route. A fallback.
β οΈ Without an
elsefallback, requesting an undefined route (like/something-random) causes the browser to hang indefinitely β the loading spinner keeps spinning because the server never sends any response back. Always include a fallback case.
π Step 4: Sending Status Codes and Headers
What Is a Status Code?
π’ An HTTP status code is a number sent back with the response, indicating the outcome of the request.
β
404is the well-known code for "Page Not Found."β
200means "OK" (a successful response) β this is the default when no other code is explicitly set.
What Is a Header?
π An HTTP header is a piece of metadata about the response (or request) β extra context sent alongside the actual content.
Setting Both with writeHead
res.writeHead(404, {
'Content-Type': 'text/html',
'my-own-header': 'hello-world'
});
π’ The first argument is the status code (
404).π¦ The second argument is an object containing whichever headers you want to send.
Common Standard Header: Content-Type
'Content-Type': 'text/html'π This tells the browser to expect HTML in the response body.
π₯οΈ Once set, you can send actual HTML content:
res.end('<h1>Page not found!</h1>');The browser will now render this as an <h1> heading instead of displaying it as plain text.
Custom Headers
π οΈ You can also define your own custom headers, for example:
'my-own-header': 'hello-world'π€« Verifying Status Codes and Headers
π οΈ Open Developer Tools:
Mac:
Cmd + J(or right-click β Inspect)Windows:
Alt + Ctrl + J(or View β Developer β Developer Tools)
π Go to the Network tab.
π Reload the page β you'll see the request listed with a
404status (often shown in red) and, if you click into it, a Response Headers section showing both standard and custom headers.

β οΈ Important Rule
β³ Status codes and headers must be set before the response body is sent.
π« You can't send headers after calling
res.end()with content β they always need to go throughres.writeHead()first.
π§ͺ Testing Everything
π Restart the server (Ctrl + C, then
node index.js) after every code change.π Visit:
π
/or/overviewβ shows "This is the OVERVIEW"π¦
/productβ shows "This is the PRODUCT"β Any other path (e.g.,
/random) β shows "Page not found!" with a 404 status and custom headers.
π Check the Network tab in Dev Tools to confirm:
β Status code (200 for success, 404 for not found)
π Response headers (
Content-Type, custom headers, etc.)
β Important Clarification: Routes β File System
Routes like
/overviewor/productaren't tied to actual folders/files in your project.Visiting
/templateswon't automatically load atemplatesfolder.To make
/templateswork, you have to explicitly define it in your routing logic and manually send back a response.
π Key Takeaways
π Concept | π― Purpose |
|---|---|
| π Gives you the path requested by the client |
If/Else on | π Implements basic routing β different responses for different URLs |
| π Prevents the server from hanging on undefined routes |
| π¨ Sets the HTTP status code and headers (must be called before |
| π₯οΈ Tells the browser to render the response as HTML |
| β Standard code for "Page Not Found" |
Routes vs File System | π Routes are custom-defined in code β they don't map automatically to folders/files |
const fs = require('fs');
const http = require('http');
const url = require('url');
////////////////////////////
//FILES
//Blocking, Synchronous way
//const textIn = fs.readFileSync('./txt/input.txt', 'utf-8');
//console.log(textIn);
//const textOut = `This is what we know about the avocado: ${textIn}.\nCreated on ${Date.now()}`;
//fs.writeFileSync('./txt/output.txt', textOut);
//console.log('File written!');
//Non-blocking, Asynchronous way
// fs.readFile('./txt/start.txt', 'utf8', (err, data1) => {
// fs.readFile(`./txt/${data1}.txt`, 'utf8', (err, data2) => {
// console.log(data2);
// fs.readFile('./txt/append.txt', 'utf8', (err, data3) => {
// console.log(data2, data3);
// fs.writeFile('./txt/final.txt', `${data2}\n${data3}`, 'utf8', (err) => {
// console.log('Your file has been written π');
// });
// });
// });
// });
/////////////////////////////
//SERVER
const server = http.createServer((req, res) => {
const pathName = req.url;
if (pathName === '/overview' || pathName === '/') {
res.end('This is the OVERVIEW');
} else if (pathName === '/product') {
res.end('This is the PRODUCT');
} else {
res.writeHead(404, {
'Content-Type': 'text/html',
'my-own-header': 'hello-world'
});
res.end('<h1>Page not found!</h1>');
}
});
server.listen(8000, '127.0.0.1', () => {
console.log('Listening to requests on port 8000');
});