Client-side routing
Three URLs, one router — running in the browser. Each is still its own static file.
server-rendered — the file the build wrote, before any JavaScript ran
Still three static files
/spa/1, /spa/2 and /spa/3 are each their own file in web/dist, screen and all. <head> stays the server's, so each carries its own title, description and social card — which is what a crawler and a link preview read, neither of them running the page.
The build finds those URLs the way it finds every other page: by reading the three <a href> above out of the rendered HTML. It never runs the router. That is the constraint to carry into your own: a route reachable only through client code is invisible to the build and will not be generated — link to it with a real href, as this does, or name it in entryPoints.