I am building a SPA with Angular 8.0.0. I am running into the exact same issue as described in this Github issue. Note that there is another related SO question with no accepted answer.
None of the suggested workarounds in the GitHub issue have worked for me. The Angular team has closed the issue and suggested posting a SO question.
Background
The app works initially when loading the root route http://localhost:4200/
The app redirects to /records/list
which works correctly.
When navigating to other routes in the application by clicking on [routerLink]
links, it works with no issues. For example, clicking on this link generated by [routerLink]
works:
http://localhost:4200/record/Item?RecordID=1
<a
[routerLink]="/record/Item]]"
[queryParams]="{RecordID: id}"
queryParamsHandling="merge"
>
{{ id }}
</a>
However, when reloading the page OR typing the link directly into the browser (without clicking on a routerlink) the app does NOT load and this error message appears.
Note: The problem happens with both ng serve in the dev environment and ng build on the web server. The problem only happens on initial load with ng serve, but it happens on any page reload or direct navigation on the ng build web server. I am using a minimal express app to run the web server and I might experiment with using nginx instead.
The browser just shows a blank screen with the error message:
Cannot GET /record/Item/detail
Console error:
Refused to load the image 'http://localhost:4200/favicon.ico' because it violates the following Content Security Policy directive: "default-src 'none'". Note that 'img-src' was not explicitly set, so 'default-src' is used as a fallback.
Here is the Angular routing module:
app-routing.module.this
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { RecordsTableComponent } from './components/records/table/records-table/records-table.component';
import { RecordLandingComponent } from './components/records/landing/record-landing/record-landing.component';
import { RecordDetailComponent } from './components/records/detail/record-detail/record-detail.component';
import { RecordStatusComponent } from './components/records/status/record-status/record-status.component';
import { RecordProposalComponent } from './components/records/proposal/record-proposal/record-proposal.component';
import { RecordsSearchComponent } from './components/records/search/records-search/records-search.component';
import { RecordChangesGuard } from './guards/records/record-changes/record-changes.guard';
import { RecordParamsGuard } from './guards/records/record-params/record-params.guard';
const routes: Routes = [
{ path: 'records/list', component: RecordsTableComponent },
{ path: 'records/search', component: RecordsSearchComponent },
{
path: 'record/:RecordType',
component: RecordLandingComponent, canActivate: [RecordParamsGuard],
children: [
{ path: '', redirectTo: 'detail', pathMatch: 'full' },
{ path: 'new', component: RecordDetailComponent, canDeactivate: [RecordChangesGuard] },
{ path: 'detail', component: RecordDetailComponent, canDeactivate: [RecordChangesGuard] },
{ path: 'status', component: RecordStatusComponent },
{ path: 'proposal', component: RecordProposalComponent },
]
},
{ path: '**', redirectTo: '/records/list' },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }