Reputation: 1953
i would like to deploy my app in Angular to production server but I have problems. App works corectly when I use only angular routing (change component, not redirecting) but when I refresh the page in browser, I get a 404 page returned from IIS (I use IIS as the web server)
Here is my angular routing:
const appRoutes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full', canActivate: [AuthGuard] },
{ path: 'home', component: DashboardComponent, canActivate: [AuthGuard] },
{ path: "profile", component: UserProfileComponent, canActivate: [AuthGuard] },
{ path: '400', component: ErrorComponent },
{ path: '401', component: ErrorComponent },
{ path: '403', component: ErrorComponent },
{ path: '404', component: ErrorComponent },
{ path: '500', component: ErrorComponent },
{ path: '503', component: ErrorComponent },
{ path: '**', redirectTo: '/404' }
]
Upvotes: 14
Views: 30925
Reputation: 550
This will work on following servers.
Apache Server
Add .htaccess on root to your project
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [L]
</IfModule>
IIS Server
Add web.config
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Imported Rule 1" stopProcessing="true">
<match url="^(.*)/$" ignoreCase="false" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
</conditions>
<action type="Redirect" redirectType="Permanent" url="/{R:1}" />
</rule>
<rule name="Imported Rule 2" stopProcessing="true">
<match url="^" ignoreCase="false" />
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
</conditions>
<action type="Rewrite" url="index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Nginx Server
make changes on server file Instead of using: try_files $uri $uri/ =404;
try using: try_files $uri $uri/ /index.html;
server {
listen 80;
listen [::]:80;
root /var/www/example.com/html;
index index.html index.htm index.nginx-debian.html;
server_name example.com www.example.com;
location / {
try_files $uri $uri/ /index.html;
}
}
Upvotes: 9
Reputation: 1653
I fix this bug by adding { useHash: true }
to RouterModule.forRoot()
in the app.module.ts
or app-routing.module.ts
. For example:
@NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(routes, { useHash: true }) // .../#/crisis-center/
],
declarations: [
AppComponent,
PageNotFoundComponent
],
providers: [
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
Upvotes: 0
Reputation: 5997
This worked for me:
Add web.config to /src
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="redirect all" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" pattern="" ignoreCase="false" />
</conditions>
<action type="Rewrite" url="./" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer></configuration>
On angular.json, on asset add
"src/web.config"
Upvotes: 0
Reputation: 327
My initial workaround was to just redirect on 404 back to root, and so far, I don't see a down-side to this. To my surprise, both the request path and parameters persist when refreshing. This is in an IIS 10 environment with Angular 9, and a Chrome-only (internal app) so there may be other factors at play that I'm unaware of that are only making this seem sustainable. Will try to remember to come back to my answer should we discover something.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<httpErrors>
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" prefixLanguageFilePath="" path="/" responseMode="ExecuteURL" />
</httpErrors>
</system.webServer>
</configuration>
Upvotes: 1
Reputation: 390
This work for angular 8, add .htaccess to your project file
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews -Indexes
</IfModule>
RewriteEngine On
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.html [L]
Upvotes: 21
Reputation: 1864
If you are using angular 6,7 this method works (If you are okay with /#/ in your URL.
In app.module.ts
import {LocationStrategy, HashLocationStrategy} from '@angular/common';
After import add following line to providers.
{provide: LocationStrategy, useClass: HashLocationStrategy}
ex:
providers: [AuthService,
AuthGuard,
FlxUiDataTable,
{provide: LocationStrategy, useClass: HashLocationStrategy}]
This will solve your issue. Read Documentation here.
Upvotes: 12
Reputation: 1953
I modified the web.config in my app:
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="redirect all" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" pattern="" ignoreCase="false" />
</conditions>
<action type="Rewrite" url="./" appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
In index.html is <base href="./">
. Refreshing the page is now ok.
Upvotes: 10