1

I have built angular website and everything is working as expected on my local machine environment.

I have published the site on a server with nginx server and now whenever I hit the URL http://example.com/login in the browser. It gives 404 not found.

I have found the other solution where I have to put # in my URL and my URL shows like http://example.com/#/login but I do not want to show # in my URL.

How can I fix this problem?

deepak
  • 161
  • 8
  • Does this answer your question? [Angular 2.0 router not working on reloading the browser](https://stackoverflow.com/questions/31415052/angular-2-0-router-not-working-on-reloading-the-browser) – WhatsThePoint Apr 04 '23 at 10:41

1 Answers1

2

1. Paths on webservers

Basically Web servers are "dumb" they serve documents that you tell them to look for. If you navigate to https://www.example.com/ you are asking for the root of the webserver. (for the rest of this answer I will use / to indicate the root of the webserver so / = https://www.example.com/).
If no default document is provided, you either get a list of the files on the webserver (if it is very old, or it has been configured to do so), a 404 (not found) or a 403 (forbidden) error.
The default document can be a list, for example for apache:

DirectoryIndex index.php index.html

This tells Apache to first look for an index.php, and if that is not found, an index.html if you have both files, the contents of index.php are displayed (after being run through the php preprocessor, if configured properly).

1.1 Anchors

The # urls work because / is redirected to your /index.html and /#<something> telling the browser that there is an anchor on the page with <something> as the name. Angular is interpreting that as the route. See answers to hash in anchor tags for more information on anchors

1.2 Angular routing and paths

When we define angular routes like /abekat angular is not asking the webserver to go find the file /abekat but it is doing some javascript "magic" and displaying what seems to be a different page (but it is actually a Single Page Application) and then rewriting the URL to show the path in the browser, which has not been asked to contact the webserver to navigate to /abekat.
When you copy the URL and go to /abekat directly, there is no angular application running to intercept the url, so your bowser asks the webserver to server the file at /abekat.

1.2.1 What the webserver does with no errorhandler

If the errordocument handler is NOT set to an angular index.html, the webserver will either send the 404 and path to whatever 404 handler is present, or just display an error.
You may also by coincidence have a naming match (for example with apache MultiViews set up) where /abekat will match /abekat.html which may result in even more confusion.

1.2.2 How angular intercepts

If the errordocument handler is set to an angular index.html, then the angular loads the page and the routing module reads the url, and tries to match it to the configured routes. If it finds one that matches, that route is triggered, and you get that page displayed.

2. Solution

Make sure that the 404 error handler on your webserver points to the correct file.

2.1 Apache

If you are using apache http server putting

ErrorDocument 404 /index.html

in your .htaccess will solve the issue. You may also add it to the server virtualhost configuration, if you so prefer

2.2 Nginx

inside your server configuration add:

    error_page 404 /index.html;
    location = /index.html {
        root /path/to/your/html;
        internal;
    }

Remember to restart your webserver to reload the configuration.

3. 404 page in angular

To have a dedicated 404 page in angular (for invalid routes) you need to create a dedicated component, for example PageNotFoundComponent and redirect ** to it like this:

app-routing.module.ts / app.module.ts

const routes: Routes = [
    { path: '', component: DefaultComponent },
    { path: 'create', component: CreateComponent },
    { path: 'edit/:someId', 
        component: EditComponent },
  
    //Wild Card Route for 404 request
    { path: '**', pathMatch: 'full', 
        component: PageNotFoundComponent },
  
];

This should be the last route in your configuration, to avoid it matching the wrong url.

JoSSte
  • 2,953
  • 6
  • 34
  • 54