35

I am following the Angular 2 routing examples. Using the "lite" webserver I am able to navigate from the root and deep linking works, but using Apache I can navigate from the root, but get 404 Not Found errors when following links direct to routes.

For example the following URL works against the "lite" webserver started on port 3000 by npm.

http://localhost:3000/crisis-center/2

But the next URL against Apache running on port 80 fails.

http://localhost/crisis-center/2
The requested URL /crisis-center/2 was not found on this server.

I did try a few .htaccess solutions recommended for similar Angular 1 issues but no luck. If anyone has had Angular 2 routing and deep linking work on Apache please do let me know how you achieved that.

@RouteConfig([
{ // Crisis Center child route
path: '/crisis-center/...',
name: 'CrisisCenter',
component: CrisisCenterComponent,
useAsDefault: true
},

{path: '/heroes',   name: 'Heroes',     component: HeroListComponent},
{path: '/hero/:id', name: 'HeroDetail', component: HeroDetailComponent},
{path: '/disaster', name: 'Asteroid', redirectTo: ['CrisisCenter',  'CrisisDetail', {id:3}]}
])

Boot.ts

import {bootstrap}        from 'angular2/platform/browser';
import {ROUTER_PROVIDERS} from 'angular2/router';
import {AppComponent}     from './app.component';
bootstrap(AppComponent, [ROUTER_PROVIDERS]);
Robert
  • 533
  • 2
  • 7
  • 13
  • 1
    Does it work with https://angular.io/docs/js/latest/api/router/HashLocationStrategy-class.html ? – Günter Zöchbauer Jan 15 '16 at 16:56
  • I did manage to get PathLocationStrategy working on Apache the following .htaccess My previous attempts had failed because there were issues with AllowOverride and mod_rewrite module 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 – Robert Jan 16 '16 at 01:59

8 Answers8

59

As the other answers don't really answer the question for if you want it to work with Apache. HashLocationStrategy remains an option, but if you want it to work as is on Apache you need to do the following:

Create a new file .htaccess in the same location as your index.html. The following code will be inside:

<IfModule mod_rewrite.c>
  Options Indexes FollowSymLinks
  RewriteEngine On
  RewriteBase /crisis-center/
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . index.html [L]
</IfModule>

(Note that in the question the <base href="/crises-center/"> inside the index.html should be identical to the RewriteBase)

Answer adapted from question+answer from Angular 2 routing and direct access to a specific route : how to configure Apache?

Rein Baarsma
  • 1,466
  • 13
  • 22
  • Thanks. I gave up on getting it to work with Apache, and did eventually get PathLocationStrategy working with nginx. I believe most of the issues are on the Angular side, and adding the following seemed to fix them. {path: '/**', redirectTo: ['Welcome']}, – Robert Apr 14 '16 at 07:35
  • Provided HashLocationStrategy link currently doesn't work and there is a typo in the link name. There is `HasLocationStrategy` and should be `HashLocationStrategy` :). Currently working link: [HashLocationStrategy](https://angular.io/docs/ts/latest/api/common/index/HashLocationStrategy-class.html) – luke May 27 '17 at 13:18
  • 6
    `RewriteRule . /index.html [L]` did not work for me. But `RewriteRule . index.html [L]` does (without `/`). – Martin Schneider Jul 06 '17 at 08:41
  • It is not working for me.I am trying direct access to a specific route.and configured Apache.My base URL and .htaccess file Options Indexes FollowSymLinks RewriteEngine On RewriteBase /// RewriteRule ^index\.html$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.html [L] Please help me – Mohit Jul 28 '17 at 11:45
  • Thank you @MA-Maddin, that solved it for me. Seems like the /index.html points to the servers root and doesn't recognize the RewriteBase. Any idea why? – user1337 Oct 20 '17 at 07:37
  • thanks, it worked. but I still have 404 problem with https? – withoutOne Jul 10 '22 at 17:28
18

For those who's running on Apache use this .htaccess

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} -s [OR]
    RewriteCond %{REQUEST_FILENAME} -l [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^.*$ - [NC,L]

    RewriteRule ^(.*) /index.html [NC,L]
</IfModule>

If you still get an error run those 2 commands:

sudo a2enmod rewrite
sudo systemctl restart apache2
Playnox
  • 1,087
  • 14
  • 9
5

For angular4/angular in app.routes.module.ts include useHash as below,

@NgModule({
  imports: [RouterModule.forRoot(routes, {useHash: true})],
  exports: [RouterModule]
})
yallam
  • 1,224
  • 1
  • 12
  • 12
  • 8
    Thanks for the down vote, can i know the reason? When people search for angular4 routing, deep linking, this page is coming up in search results. So as explained i added a solution for angular4 as well. Stop being a coward and down voting with out a reason. It takes time for me to add this solution, i am just trying to help people same as me. – yallam Aug 12 '17 at 21:43
  • 1
    Thanks Yallam. Its working for me but i have one issue with this... my URL starts with "#/" how can i fix this. I don't want to see # in the url – Farid Abbas Dec 12 '17 at 13:29
  • It because you used the hash strategy @FaridAbbas. The by default strategy used by angular is Path Location Strategy which has many features like SEO friendly etc. Look at this article https://codecraft.tv/courses/angular/routing/routing-strategies/ – Suhel Jan 30 '18 at 06:49
  • 1
    downvoted because no decent developer should ever use a hashtag without no partical reason in an angular2 app... – Playdome.io Jun 12 '18 at 16:41
  • using hash is a hack around, only valid if you're building full-stack on the same proxy (when you have API serving on the same domain and you need separation) – Playnox Jul 05 '19 at 15:21
4

According to Rein Baarsma answer you have to create .htaccess file and put it in the same directory as your index.html on your Apache server. It might be for example htdocs directory, but this depends on your Apache configuration.

However I use different .htaccess file content and it works for me for all links/routes without necessity to specify rewrite base:

<IfModule mod_rewrite.c>
  Options Indexes FollowSymLinks
  RewriteEngine On
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

It is a modification of code provided by Rein Baarsma.

My app is Angular 2+ (4.x.x) application based on angular-cli project. It hardly depends on direct URLs to addresses provided by Angular routing. Without .htaccess file above I got 404 not found after clicking every direct URL link. Now with use of this .htaccess file everything works fine.

luke
  • 3,435
  • 33
  • 41
2

If you are working with the ionic build and upload your site on hosting server then you need to add the .htaccess file on your root directory inside the www folder.

    RewriteEngine on
    RewriteCond %{REQUEST_FILENAME} -s [OR]
    RewriteCond %{REQUEST_FILENAME} -l [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^.*$ - [NC,L]
    RewriteRule ^(.*) / [R=302,NC,L]


Anju Batta
  • 104
  • 4
1

You have to make your server handle all routes back to index.html or use HashLocationStrategy

(https://angular.io/docs/ts/latest/api/common/index/HashLocationStrategy-class.html)

Take a look at:

Is Angular 2's Router broken when using HTML5 routes?

Community
  • 1
  • 1
Langley
  • 5,326
  • 2
  • 26
  • 42
  • 4
    Thanks, the stackoverflow link was useful, and there is a rather interesting issue on github about forcing front end developers to modify webserver configurations. I predict a lot of time wasted when people develop on lightweight webservers and then try to deploy to the real world. – Robert Jan 16 '16 at 02:06
  • Yes I personally didn't like the fact that they made this mode the default mode without any other warning, but if you switch to HashLocationStrategy it should work without you having to go do anything in the backend server. – Langley Jan 16 '16 at 02:10
  • I have switched to HashLocationStrategy as that seems to have the least issues. – Robert Jan 22 '16 at 00:45
1

Either in httpd.conf or in apache2.conf add the following:

<Directory "/var/www/html/">
    Options FollowSymLinks
    Allow from all
    AllowOverride All
</Directory>
  • Change "/var/www/html/" to your website location

And in .htaccess paste:

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
Misha
  • 5,260
  • 6
  • 35
  • 63
0

This generator worked for me and my HostMonster account which uses Apapche HTTPD. The .htaccess file it generated worked out of the box:

https://julianpoemp.github.io/ngx-htaccess-generator/#/generator

# Generated with ngx-htaccess-generator v1.0.7
# https://julianpoemp.github.io/ngx-htaccess-generator/


<IfModule mod_rewrite.c>
  RewriteEngine On
  
  # Redirection of requests to index.html
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -s [OR]
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
  RewriteRule ^.*$ - [NC,L]
  # Redirect all non-file routes to index.html
  RewriteRule ^(?!.*\.).*$ index.html [NC,L]
</IfModule>

Thank you, Julian Pömp!

Amar Premsaran Patel
  • 1,293
  • 7
  • 17
  • 26