Premier League Predictor: FastAPI & PostgreSQL — Chapter 12, Exercise 3
====================================================
TASK
Explain why the tag fix works without ever needing to change on
the localhost:8000 version of the app, tracing the explanation back to
how a browser resolves a relative URL.
SOLUTION
A browser resolves a relative URL (one with no leading slash, like
fetch('api/seasons')) against the document's own "base URL." By
default, that base URL is simply the URL of the page itself, up to and
including its own final path segment being dropped in favor of the
directory it lives in. The tag exists specifically
to override that default and tell the browser to use a different base
URL instead, for every relative URL resolution on that page — links,
scripts, and fetch() calls alike.
On the deployed version, mounted at /predictor/, the page is loaded
from something like https://example.com/predictor/index.html, and the
explicit tag tells the browser to resolve
every relative path against /predictor/ specifically, so
fetch('api/seasons') becomes
https://example.com/predictor/api/seasons — correctly routed through
nginx's own /predictor/ location block.
On localhost, the app is already served from the root —
http://localhost:8000/index.html. With no tag present at all,
the browser falls back to its own default behavior: resolving a
relative URL against the current page's own location, which is already
http://localhost:8000/. fetch('api/seasons') resolves to
http://localhost:8000/api/seasons — exactly the correct URL, with
zero configuration needed, because the default base URL the browser
would have used anyway already happens to be the site root.
In other words: the tag doesn't change how relative URL
resolution works — it only overrides WHERE that resolution starts
from. Since localhost's own default starting point (the page's own
actual location) is already correct, there's nothing for a tag
to override there; it's only needed once the real starting point (the
deployed page's own sub-path location) diverges from what the app was
originally written assuming.
WHY THIS WORKS AS AN ANSWER
----------------------------
It explains the real browser mechanism (relative URLs resolve against
a base URL, which defaults to the current page's own location unless
overridden), and traces precisely why that default already produces
the correct result on localhost while needing an explicit override
once the app is genuinely mounted somewhere other than the root.