38

I Have an Angular application. I run the command ng build --prod --aot to generate the dist folder. In the dist folder I created a file named Staticfile then I uploaded the dist folder to pivotal.io with the following commands:

  1. cf push name-app --no-start
  2. cf start name-app

The app runs well. I have a nav bar, so when I change the path with navbar everything works fine. But when I do it manually (I enter the url myself) I have this error 404 Not Found nginx. This my app.component.ts:

const appRoutes: Routes = [
  { path: 'time-picker', component: TimePickerComponent },
  { path: 'material-picker', component: MaterialPickerComponent },
  { path: 'about', component: AboutComponent },
  { path: 'login', component: LoginComponent },
  { path: 'registration', component: RegistrationComponent },
  {
    path: '',
    redirectTo: '/time-picker',
    pathMatch: 'full'
  }
];

@NgModule({
  declarations: [
    AppComponent,
    TimePickerComponent,
    MaterialPickerComponent,
    DurationCardComponent,
    AboutComponent,
    LoginComponent,
    RegistrationComponent,
  ],
  imports: [RouterModule.forRoot(
    appRoutes
    // ,{ enableTracing: true } // <-- debugging purposes only
  ),
    FormsModule,
    BrowserAnimationsModule,
    BrowserModule,
    MdCardModule, MdDatepickerModule, MdNativeDateModule, MdInputModule

  ],
  providers: [{ provide: DateAdapter, useClass: CustomDateAdapter }],
  bootstrap: [AppComponent]
})
export class AppModule {
  constructor(private dateAdapter: DateAdapter<Date>) {
    this.dateAdapter.setLocale('fr-br');
  }
}
Melchia
  • 19,807
  • 18
  • 90
  • 103

8 Answers8

73

for those not using a Staticfile might wanna try this.

I had the same problem with nginx serving angular. The following is the default config file, probably found somewhere in /etc/nginx/sites-available/yoursite

     location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            try_files $uri $uri/ =404;
    }

but what we acctually want is...

     location / {
            # First attempt to serve request as file, then
            # as directory, then redirect to index(angular) if no file found.
            try_files $uri $uri/ /index.html;
    }
Marko Letic
  • 2,320
  • 2
  • 26
  • 33
Sven Dhaens
  • 1,616
  • 1
  • 14
  • 10
  • Yes you're right. This method works too. But in my case I was using PWS which is a PaaS, so it couldn't work. +1 though for it could help people in the future – Melchia Jan 07 '18 at 18:17
  • Hi I'm really confused on how to actually get to /etc/nginx/sites-available/yoursite for my react app. Please help. – John Aug 07 '20 at 08:33
  • @John, this path is where nginx configuration would be found if you are on Unix-based OS, and ofc are using nginx., is this the case for you? – Sven Dhaens Aug 07 '20 at 08:57
  • I'm on a windows machine @Sven. How do I get to the location? Any ideas? – John Aug 10 '20 at 08:13
  • @John read up on http://nginx.org/en/docs/windows.html – Sven Dhaens Aug 11 '20 at 06:50
  • You saved me with the `/` at the beginning of `/index.html` – Chgad Jun 09 '21 at 16:01
39

In your nginx.conf file try using:

try_files $uri $uri/ /index.html;

instead of:

try_files $uri $uri/ =404;

That worked for me on Angular 5 project.

rje
  • 5,930
  • 1
  • 18
  • 38
Mad Javad
  • 434
  • 4
  • 5
  • 1
    this exactly what @Marko Letic said. What is the difference in this answer? – Paulo Guimarães Jan 28 '21 at 19:50
  • If anyone is trying this solution and did not work. Check your nginx.conf if you did not miss adding root /dist of your index.html file. This is what happens to me forgot to add root /pathofmydist – Bryan Lim May 28 '22 at 16:26
13

I finally found the answer: After I generated the dist folder.

  • I created a file called Staticfile and put it in the dist folder
  • I opened Staticfile & I added this line pushstate: enabled

pushstate enabled keeps browser-visible URLs clean for client-side JavaScript apps that serve multiple routes. For example, pushstate routing allows a single JavaScript file route to multiple anchor-tagged URLs that look like /some/path1 instead of /some#path1.

Melchia
  • 19,807
  • 18
  • 90
  • 103
3

This is a problem with the server side not the Angular side of things . It is the servers responsibility to return the index or the landing page for each request in your case nginx.

UPDATE

If you by any means do not have a backend or server where you can configure this there are two workarounds.

  • Using HashLocationStrategy in Angular
  • Making some tweak in index.html file link No -15
Rahul Singh
  • 17,747
  • 8
  • 56
  • 83
  • i have a workaround for this problem if you donot want to go via the nginx config way but mind it is a strict work around [link](https://rahulrsingh09.github.io/AngularConcepts/faq) check the question 15 [last one] – Rahul Singh Aug 24 '17 at 10:26
  • I already told you Sir that all I did was creating an Angular application. I have done no work in the back end – Melchia Aug 24 '17 at 10:32
  • this is a work around for the frontend only , please check the link in the comment sir . you need to make that change in your index.html. I will update in the answer too – Rahul Singh Aug 24 '17 at 10:35
  • @Melchia hope you get it now – Rahul Singh Aug 24 '17 at 10:39
  • I don't understand, I visited your website nothing is there – Melchia Aug 24 '17 at 10:53
  • I went here https://rahulrsingh09.github.io/AngularConcepts/home#collapse15 – Melchia Aug 24 '17 at 10:55
  • @Melchia that is solution i was talking about it works on ghpages as well as for this scenarios. I hope – Rahul Singh Aug 24 '17 at 10:59
  • No the problem you'talking about is different. I don't have this error when I refresh my page , I get this error only when I manually enter the URL – Melchia Aug 24 '17 at 12:55
2

For me it was a permission issue, Nginx has to be the owner of the directory where you put your dist, i've seen this error in the nginx log file

"root/../../dist/index.html" failed (13: Permission denied)

so i gave permissions to nginx user on the top folder containing my dist

chown nginx . -R //  to give nginx the permissions on the current directory, and everything in it.

and then you have to restart nginx

sudo systemctl restart nginx

and it should work!

Fateh Mohamed
  • 18,689
  • 5
  • 37
  • 48
  • After everything was failing for me, I saw your answer way down here and realized I had to restart nginx – fix Apr 02 '20 at 01:31
1

Angular applications are single page applications. When you type the address manually you try to route to a location where the application is not running.

You need to edit nginx config to route to your base page.

Carsten
  • 3,724
  • 23
  • 27
  • I don't have nginx config, the only steps I did are the ones I wrote above. I just added a Staticfile and then pushed the dist folder. – Melchia Aug 24 '17 at 10:21
  • https://stackoverflow.com/questions/39612339/how-can-i-deploy-my-angular-2-typescript-webpack-app – Carsten Aug 24 '17 at 10:25
  • How to config nginx for pivotal.io. I don't have a server side all I did was in Front end side. – Melchia Aug 24 '17 at 10:31
0

This is actually an nginx configuration issue following this required to overcome this issue.

In your nginx.conf file try using:

try_files $uri $uri/ /index.html;

instead of:

try_files $uri $uri/ =404;

Then afterward also to need change the following.

from:

 error_page 404 index.html;

To

error_page 404 /actualPathToDistFolder/index.html;
0

I assume your all data of /dist directory is now in /var/www/your-domain/, if not then first paste on that

now your url is only accepted homepage or landing page otherwise they show 404 error.

In this condition find your ngnix's /default file, In Linux path like that /etc/nginx/sites-available/default, In this file, you will see like that

try_files $uri $uri/ =404

replace with

try_files $uri $uri/ /index.html;

now you restart your ngnix server with command in linux

sudo systemctl restart nginx

and see status of ngnix with

sudo systemctl status nginx
rajkanani
  • 75
  • 1
  • 4