What are the parts of a URL?
A URL is an address with several parts, each with its own job. Take http://localhost:3000/hours?day=saturday#bread. The protocol, http, says how to talk to the server. The host, localhost, says which computer. The port, 3000, says which program on that computer. Everything after that is aimed at your code.
The path, /hours, names the page. The query string, ?day=saturday, carries extra values as name and value pairs. The fragment, #bread, points to a spot inside the page once it has loaded.
Live sites usually hide two of these. Browsers fill in port 443 for https and port 80 for http, so you rarely see a port outside development. And the path for a home page is /, which browsers add even when you type only the domain.
http://localhost:3000/hours?day=saturday#bread
protocol http
host localhost
port 3000
path /hours
query ?day=saturday
fragment #bread (stays in the browser)

Which parts of the URL reach your server?
The browser uses the protocol, host and port to find your server, and sends the host and port along in the Host header. The path and query string travel in the first line of the request, as in GET /hours?day=saturday. Express splits them for you: req.path is /hours and req.query.day is 'saturday'.
The fragment never leaves the browser. It is there for the page itself, to scroll to a heading or to keep track of a tab. Your server can’t read it, log it or route on it. If someone asks why their #section doesn’t show up in req.url, that is the reason.
Press **GET /hours?day=saturday** after you finish the task. The Requests view shows the full path with its query, and the route that handled it is still app.get('/hours'). Query strings get a lesson of their own later in the course.
How does Express choose a route?
A route is a pair of a method and a path, plus the function to run. app.get('/menu', handler) matches requests whose method is GET and whose path is /menu. A POST /menu doesn’t match it, and neither does GET /menus.
When a request arrives, Express walks through your routes from top to bottom, in the order the code added them. It runs the first one whose method and path both match. If that handler sends a response, the search stops there. If nothing matches by the end of the list, Express answers 404 with its “Cannot GET” page.
That order is why placement matters. Two routes with the same method and path never both run for one request. Only the upper one answers, and the lower one sits there doing nothing, which is exactly the bug hidden in the Break It server.
app.get('/menu', (req, res) => {
res.send('Menu coming soon'); // this one wins
});
app.get('/menu', (req, res) => {
res.send('Rye, sourdough'); // never runs
});Does /Menu/ match the same route as /menu?
By default, yes. Express ignores letter case when matching paths, so /MENU reaches app.get('/menu'). It also accepts one trailing slash, so /menu/ matches as well. Press **GET /MENU/** to see it land on the menu route.
Both behaviours are settings. app.set('case sensitive routing', true) makes /Menu and /menu different pages, and app.set('strict routing', true) makes the trailing slash count. Most sites leave the defaults alone, since visitors and old links rarely type a path perfectly.
Search engines see /menu and /menu/ as two different addresses, even though your server answers both. Pick one form and use it in every link you write. The later lesson on status codes shows how to send visitors from one address to the other with a redirect.
How do you plan routes for a small site?
Start from the pages a visitor needs, then give each one a short, lower-case path made of plain words. For the bakery that is / for the welcome page, /menu for the bread, /hours for opening times and /contact for the email and address. Use hyphens between words, as in /opening-hours, and avoid spaces and capital letters.
Paths are part of what people share and bookmark. Once a link is printed on a flyer or saved in someone’s browser, changing it breaks that link. Choosing clear names now saves redirects later.
Keep the routes for one site together in server.js, in an order that matches how you think about the site. When the file grows, later lessons split routes into groups with express.Router().
/is the home page./menulists the bread and pastries./hoursshows when the shop is open./contactgives the email and address.
Why does a missing slash break a route?
Every request path starts with /, even the home page. A route written as app.get('contact', ...) compares contact with /contact, and the two never match. The server starts without any warning, and the page answers 404 forever.
Typos behave the same way. A route for /hous is valid code, so nothing complains until someone asks for /hours. The quickest way to catch both is to read the Requests view: a 404 that says “no route matched” for a page you know you wrote means the route’s path differs from the one being asked for.
How do you check routes in the Requests view?
Send every page once after you change routes. For each exchange the Requests view shows which route handled it, such as app.get('/hours'), or says that no route matched. That line answers the two questions that matter: did any route run, and was it the one you meant.
Use the Browser view for the visitor’s side. Type a path into the request bar, press Send, and the page appears as a browser would draw it. When the Browser view shows something unexpected, switch back to the Requests view and read the route line before touching any code.
What should you look for in AI-written routes?
AI tools often leave placeholder routes from an earlier draft above the real ones, or add a second route for a path that already exists. Search the file for each path you care about and make sure it appears once per method. Also watch for paths without a leading slash, mixed naming such as /openingHours next to /contact-us, and a catch-all route placed near the top where it swallows every request below it.
Before you accept the code, list every path the site should answer, send each one, and confirm the Requests view names the route you expect.
Ask the tool to explain any route whose path you didn’t expect. If it added /home next to /, or /menu.html next to /menu, decide which address you want visitors and search engines to use and keep only that one. Fewer routes mean fewer places for a typo to hide.
Field notes
- A URL has parts like protocol, host, port, path and query, and each has its own job.
- Your route sees the path and the query string, while the browser uses the rest to find the server.
- A route pairs a method and a path with a function to run, such as
app.get('/menu', handler). - Every route path starts with
/, so'contact'without the slash never matches.
Easy to get wrong
Request paths always begin with a slash, so a route path without one never matches and the page answers 404.
Express stops at the first route that answers. The second /menu route can never run, so the visitor keeps seeing the placeholder.
Browsers never send the part after #. The server only receives the path and the query string.
Questions people ask
Can two routes have the same path?
Yes, when their methods differ. app.get('/orders') and app.post('/orders') are separate routes for reading and adding orders. Two routes with the same method and the same path are a mistake, because only the first one answers.
Why does /menu/ work even though I wrote /menu?
Express accepts one trailing slash by default. Turn on strict routing if you need the two forms to behave differently, and pick one form for all your links either way.
What is the difference between a URL and a route?
A URL is the full address a visitor uses. A route is a rule in your server that matches part of it, the method and the path, and says which function should answer.
Are paths case-sensitive on a real server?
Express ignores case by default, as the practice server does. Files served from disk can behave differently: on Linux, which most hosts run, Logo.png and logo.png are different files.