13

I have an angular 4 project and when I run it from localhost:4200/route-a, it works fine and when I refresh the browser, all works well as expected. However, when I build it with ng build and run it from apache, navigating to localhost/route-a returns a 404. Here is my code for routing:

imports: [BrowserModule, HttpModule, FormsModule, RouterModule.forRoot([
    { path: 'home', component: HomeComponent },
    { path: 'route-a', component: RouteAComponent },
    { path: '', redirectTo: '/home', pathMatch: 'full' }
  ])]
Derek Brown
  • 4,232
  • 4
  • 27
  • 44
Wafula Samuel
  • 530
  • 1
  • 8
  • 25
  • You have to [configure your apache server](https://ngmilk.rocks/2015/03/09/angularjs-html5-mode-or-pretty-urls-on-apache-using-htaccess/#thecode) to allow html5routing – Pankaj Parkar Jun 29 '17 at 07:56
  • Because it's not a route like a server would do : it's a route that loads an html template. If you want to make it work, you will have to set your server to redirect to every route you made. –  Jun 29 '17 at 07:57
  • Thanks guys let me try it out – Wafula Samuel Jun 29 '17 at 07:58

3 Answers3

36

It is not an Angular issue. It is a problem with your apache settings. When you are using HTML5 mode(pretty url) in Angular, you will have to config your Apache to send all request where the resource doesn't exist on the server to the index.html file.

This can be done with the following .htaccess configuration:

RewriteEngine On  
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]

# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html

The reason is that when you try to access /route-a, the apache server will be default try to find the directory route-a and the index.html file within. But because you do not have that directory, will apache return a 404 error.

But by telling apache, that on any request where the location or file do not exist. To send send your Angular html file indsted, will the Angular router take it from there.

Doehl
  • 386
  • 5
  • 5
8

As of Apache version 2.2.16, you can use the FallbackResource directive for this:

<Directory "/var/www/my_blog">
  FallbackResource index.php
</Directory>

Check https://httpd.apache.org/docs/trunk/rewrite/remapping.html#fallback-resource

Catfish
  • 18,876
  • 54
  • 209
  • 353
4

Sometimes there could be that you don't have access to the server configuration. There is another possible solution to this.

In the import of the RouterModule where there is something like:

RouterModule.forRoot( routes )

You can add the useHash this way:

RouterModule.forRoot( routes, { useHash: true } )

then rebuild your project with the production flag and the URLs now will be like:

http://yourserver/#/page1/

this way, thanks to the hash, the app will work without any problems and the only thing needed is setting the useHash on the RouterModule and rebuilding your app.

The rewrite rules are good but I think it is good having more options.

jeprubio
  • 17,312
  • 5
  • 45
  • 56