I’m having a bit of an issue with an Angular application I have built (v. 17). It works perfectly fine, but I’m utilising a lot of dynamic routes, and these need to be rendered on the server. For example, I have a route /game/:id/:slug
where id
and slug
are dynamic.
I have built the application and copied over the files to a location nginx can access them, and have the following config in Nginx:
server {
listen 80;
server_name domain.com;
root /var/www/html/frontend/server;
gzip on;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
location /robots.txt {
alias /var/www/frontend/robots.txt;
}
location / {
try_files $uri /index.html @backend;
}
location @backend {
proxy_pass http://localhost:4000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_cache_bypass $http_upgrade;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Which is based off some config that I saw in another thread on here (I have also tried /var/www/html/frontend/browser, which gives the same results) . I have then ran the Angular app using pm2 via pm2 start server.mjs --name "app"
.
Everything runs perfectly, but I have noticed that when going to a dynamic route, such as /game/1/slug
, the index.html file is loaded first, and then the correct component is loaded and all the data after the API request has been made on the client/browser.
This is causing a huge issue for me in terms of Google. They did index one page, but they indexed the index.html
page for the link /game/1/slug
, I assume because that is what they saw first before the component loaded. Since then, however, Google is refusing to index any of the pages citing a ‘soft 404’ error.
I’m not sure if I’m doing something obviously wrong here, or why none of my API requests are being made on the server? I can see all of the API calls (GET) being made in the browser console instead of on the server.
I’m using the default server.ts file:
export function app(): express.Express {
const server = express();
const serverDistFolder = dirname(fileURLToPath(import.meta.url));
const browserDistFolder = resolve(serverDistFolder, '../browser');
const indexHtml = join(serverDistFolder, 'index.server.html');
const commonEngine = new CommonEngine();
server.set('view engine', 'html');
server.set('views', browserDistFolder);
// Serve static files from /browser
server.get(
'*.*',
express.static(browserDistFolder, {
maxAge: '1y',
}),
);
// All regular routes use the Angular engine
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: req.baseUrl },
{ provide: 'REQUEST', useValue: req },
{ provide: 'RESPONSE', useValue: res },
],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
return server;
}
function run(): void {
const port = process.env['PORT'] || 4000;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
run();
Does anyone have any ideas/pointers in the right direction of what I’m potentially doing wrong here? I assume its something very obvious that I can’t seem to figure out.