skip to Main Content

I ask this question because I’m not sure if from the frontend or backend is the solution to my problem.

Basically, I have the problem that when reloading the page in a different route from the start "/", I get the error "not found 404", I have seen some possible solutions such as include a “hash” but for SEO issues I can not do it. I have also seen that there are configurations to solve this problem, but these configurations are in apache servers or in ISS.

My application works fine while using angular-cli with ng serve, but when I run

ng build --prod --base-href=./ and --deploy-url=./

the routes do not work when I reload the page.

For example:

http://localhost/my_folder_compilated/programa/detalle-programa/5cf7d27faa8e180017211754    --> 404 not found!

I need to deploy it on a Heroku server or in its absence any that works on nodejs.

How can I solve this problem?

// this is the route that I have in my app.routing.ts
{path: 'programa/detalle-programa/:programaId', component: 
DetalleProgramaComponent},
{path: '**', component: NotFoundComponent}

Note

I think the solution is in the backend. I’m using nodejs (express), but I can not fix it.

Update

I am using this code and works well well for my routes,

const distDirectory = path.join(__dirname, 'public');

app.get('*', function (req, res, next) {
const file_path = path.join(distDirectory, req.url.split('?').shift());
console.log(file_path)
if (fs.existsSync(file_path)) next();
else res.sendFile(path.join(distDirectory, 'index.html'));
});

app.use(express.static(distDirectory));

except for this one:

localhost/programa/detalle-programa/5cf7d27faa8e180017211754

and in console this is the route that I a receiving:

   ...publicprogramadetalle-programaruntime.366eb317d0165de30d51.js

obviously it does not exist and it marks an error in my files

Update 2:

The folder on my server heroku is:

public --> here my files, and the index.html 

and my index.html is:

<head>
    <meta charset="utf-8">
    <title>title</title>
    <base href="/">

    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" type="image/x-icon" href="favicon.ico">
    <link rel="stylesheet" href="styles.51e30e538d2560c1a9e9.css">
</head>


<body>
    <app-root ></app-root>
    <script type="text/javascript" src="/runtime.a5dd35324ddfd942bef1.js">
    </script>
    <script type="text/javascript" src="/polyfills.3eb7881d3a00da6c675e.js">
    </script>
    <script type="text/javascript" src="/scripts.dd86f002a5aef1b13f0f.js">
    </script>
    <script type="text/javascript" src="/main.23ac360bc829b49bc07d.js">
    </script>
</body>

</html>

The problem that happens to me is that all the requests I get that I’m doing are returning my index.html file, that’s why the promises of my services can not be resolved.

2

Answers


  1. You have to redirect all routes to your Angular app’s index.html. This is because your frontend handles the navigation, not the backend.

    If you are for example using express, you can have a catch-all route:

    server.get('/*', (req, res) => {
      res.sendFile(__dirname + '/index.html');
    })
    
    Login or Signup to reply.
  2. Use the following settings in your express index.js file, set the distDirectory
    to your dist directory.

    const path = require('path');
    const express = require('express');
    const fs = require('fs');
    
    const app = express();
    
    const distDirectory = path.join(__dirname, 'dist');
    
    app.get('*', function (req, res, next) {
        const file_path = path.join(distDirectory, req.url.split('?').shift());
        if (fs.existsSync(file_path)) next();
        else res.sendFile(path.join(distDirectory, 'index.html'));
    });
    
    app.use(express.static(distDirectory));
    
    app.listen(80, function () {
        console.log('listening');
    });
    

    Update: using above code your routes are working, but you are getting 404 for
    JavaScript and CSS files. The reason is:

    // Never use a leading dot in base-href
    ng build --prod --base-href=./
                                ^^
    

    Few examples of valid base-url:

    website url: http://localhost/my_folder_compilated/
    base url:    /my_folder_compilated/
    
    website url: http://localhost:4200/public/
    base url:    /public/
    

    N.B: You don’t need to set --deploy-url=./, use base-url only.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search