Angular 17 SSR baseHref / baseUrl is not respected
Which @angular/* package(s) are the source of the bug?
platform-server
Is this a regression?
Yes
Description
Maybe I'm stupid or don't see something, but I think there is something wrong. I want to deploy an angular ssr app under a subpath of a domain, for example https://example.org/myapp. This subpath is handled by an nginx reverse proxy. So far so good.
Now I'm adding baseHref to the angular.json. It gets added to the index.html, everything fine. But if I'm looking to the server.ts I see the following:
server.get('*.*', express.static(browserDistFolder, {
maxAge: '1y',
}));
server.get('*', (req, res, next) => {
const { protocol, originalUrl, baseUrl, headers } = req;
commonEngine
.render({
bootstrap,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: browserDistFolder,
providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
But the baseUrl is always empty. Because the baseUrl can only be set if the code would look like this:
const router = express.Router();
router.get('*.*', express.static(browserDistFolder, {
maxAge: '1y',
}));
router.get('*', (req, res, next) => {
const { protocol, originalUrl, baseUrl, headers } = req;
commonEngine
.render({
bootstrap,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: browserDistFolder,
providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
server.use('/myapp', router);
Without using .use() the baseUrl MUST be empty. So I don't understand the whole purpose behind the default code? And of course it's not working with the default code, otherwise I wouldn't write.
So it looks like this scenario is not possible without changing the server.ts fundamentally. And it would be nice, if this changes are described in the docs.
Or if they were the default and changes to the baseHref option in the angular.json would also affect the server.ts. That I don't have to change the server.use() part manually.
Please provide a link to a minimal reproduction of the bug
No response
Please provide the exception or error you saw
No response
Please provide the environment you discovered this bug in (run ng version)
Angular 17.3.1
Anything else?
No response
I'm having the same problem and I'm banging my head reading so many things online that don't work.
I opened a issue to this problem at the past.
I'm still having the same problem and was looking if Angular 16 have solved this issue, but apparently not.
I don't understand either why the code providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }], is there if does nothing (probably I don't understand) and don't have any documentation on how to use it.
If I already have defined that on app.module, index.html and angular.json, on my opinion it should get this info from one of those places, and not from express request.
Even if you change baseUrl to a string it don't serve the app in a subpath.
On Angular 17 I did a test using this to generate an app npx @angular/cli@latest new --standalone false --ssr --package-manager pnpm ssr17.
It seems that works just setting the base href in the index.html, the files are served with the right path http://localhost:4000/my-sub-path/styles-5INURTSO.css
The file loads ok on the browser but I get this console error.
ERROR G [Error]: NG04002: 'my-sub-path/styles-5INURTSO.css'
at vp.noMatchError (file:///home/user/dev/temp/ssr17/dist/ssr17/server/chunk-6RJGDO77.mjs:43:74932)
at file:///home/user/dev/temp/ssr17/dist/ssr17/server/chunk-6RJGDO77.mjs:43:75629
at file:///home/user/dev/temp/ssr17/dist/ssr17/server/chunk-6RJGDO77.mjs:4:16474
at Tu._error (file:///home/user/dev/temp/ssr17/dist/ssr17/server/chunk-6RJGDO77.mjs:4:5497)
at Tu.error (file:///home/user/dev/temp/ssr17/dist/ssr17/server/chunk-6RJGDO77.mjs:4:2594)
at Tu._error (file:///home/user/dev/temp/ssr17/dist/ssr17/server/chunk-6RJGDO77.mjs:4:2834)
at Tu.error (file:///home/user/dev/temp/ssr17/dist/ssr17/server/chunk-6RJGDO77.mjs:4:2594)
at Tu._error (file:///home/user/dev/temp/ssr17/dist/ssr17/server/chunk-6RJGDO77.mjs:4:2834)
at Tu.error (file:///home/user/dev/temp/ssr17/dist/ssr17/server/chunk-6RJGDO77.mjs:4:2594)
at Tu._error (file:///home/user/dev/temp/ssr17/dist/ssr17/server/chunk-6RJGDO77.mjs:4:2834) {
code: 4002
}
Restore the base href to default <base href="/"> and setting it up on the app.module.ts on @NgModule providers don't work.
providers: [
provideClientHydration(),
{provide: APP_BASE_HREF, useValue: '/my-sub-path'}
]
The page loads ok on my dev machine on the url http://localhost:4000/my-sub-path/, but it's loading the files from the root path http://localhost:4000/styles-5INURTSO.css and don't respect the subpath http://localhost:4000/my-sub-path/styles-5INURTSO.css
With index.html with <base href="/"> the @NgModule without the APP_BASE_HREF and setting up baseHref on angular.json on both prod and dev configurations keys.
The app seems to work, it's serving the files right but the console logs error mentioned above persists.
And in all cases the baseUrl it's empty on the server.ts
const { protocol, originalUrl, baseUrl, headers } = req;
console.log("baseUrl -> ", baseUrl);
commonEngine
...
Always yield baseUrl -> an empty value.
Please document more stuff on the server.ts, what things should do, and possible modifications.
I know that it's express and angular don't have to provide documentation on express, but on the integration on both there was never documentation about it.
Please Please Please, write a angular(.dev|.io) page on how to properly serve a angular SSR app on a subpath.
I cannot migrate my app to the latest version (17.3.0) right now but since @JustDoItSascha it's having a different behavior from what I tested, maybe ssr still have some quirkies.
The question that remains is, why there is that provider in the server.ts I'm trying to understand this for the last 4 years.
here is your reason https://github.com/angular/angular-cli/issues/26323 APP_BASE_HREF is cannot pass to client, so SSR not work as expect. It is hidden breaking change
Is the same logic use for ngServe as well? In that case these bugs could be related:
- https://github.com/angular/angular-cli/issues/27795
- https://github.com/angular/angular-cli/issues/27576