When you write an address in the browser, you are telling the browser to go to a server and give you some data.
The way an SPA(single page app) works is that the server loads an html with JavaScript and then executes all of the logic on the client, like fetching data, rendering, navigation, without the need to load the whole page again from the server.
Then, whenever you navigate in your application, from the links of the app, without refreshing the browser, you won't hit the server, but you will see content changes in the browser.
However, when you refresh the browser, you will hit the server.
But, if the routes are only defined in the client app, how does the server know what data to give you?
The server gives you the same data every time, an html file with JavaScript, and then the JavaScript does the routing and provides the data in the browser.
That's why when you right click/view page source, you don't see any data in the page source, just some empty html and some js scripts, unless the data is hardcoded in the html.
When you have a SSR application, things change a bit. For whatever route you define in your client router, the server knows to render that data from the server.
How does this happen?
The server has, in its router, a wildcard route that, for whatever route you write in the browser, it renders the html with the js.
app.get('*', (req, res) => {
res.render(indexHtml, {
req,
providers: []
});
});
The data is populated in the html, because the SPA is written in such a way that it does all of the http calls on the server, when you refresh the page, but then switches on the client, when you start client navigation.
But on the same server, you can define other routes, that when they are called, render some other data than the SPA.
For example:
app.get('/my-super-route', (req, res) => {
console.log('hello server');
res.send({
myData: 'hello there from the server!!!'
})
})
This route can be called from the SPA, with an http get
call or directly from the browser.
That's why you have two routers, but one app. The router of the server and the router of the SPA.
See some exaples in the video below: