20

I am trying to host an angular 2 app (created with angular cli) with Firebase but my routes are not working.

I created a project with angular 2 and typescript for a site I am working on where I want a static privacy-policy page.

When I perform

ng serve

and navigate to http://localhost:4200/privacy-policy in my browser I get the content I expect.

Here is the code as recommended by the angular 2 route page-

@NgModule({
    declarations: [
        AppComponent,
        HomeComponent,
        TermsOfServiceComponent,
        PrivacyPolicyComponent,
        PageNotFoundComponent
    ],
    imports: [
        AlertModule,
        BrowserModule,
        FormsModule,
        HttpModule,
        RouterModule.forRoot([
            {path: 'privacy-policy', component: PrivacyPolicyComponent},
            {path: 'terms-of-service', component: TermsOfServiceComponent},
            {path: '', component: HomeComponent},
            {path: '**', component: PageNotFoundComponent}
        ])
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule {
}

I configured Firebase hosting with my project here is my config file-

{
  "database": {
    "rules": "database.rules.json"
  },
  "hosting": {
    "public": "dist"
  }
}

To Deploy I run

ng build --prod
firebase deploy

When I navigate to https://MY-APP.firebaseapp.com/ The app loads fine for the default route.

However when I try to navigate to https://MY-APP.firebaseapp.com/privacy-policy I get 404.

I would have expected this to work as it did with ng serve.

Any help would be greatly appreciated.

adjuremods
  • 2,938
  • 2
  • 12
  • 17
Philip Brack
  • 1,340
  • 14
  • 26

4 Answers4

49

Late response, but since i faced the same problem today when i deployed my app on Firebase, here is the quick fix for it:

In your firebase.json file, update your hosting key by defining rewrite rules:

  "hosting": {
    "public": "dist",
    "rewrites": [ {
      "source": "**",
      "destination": "/index.html"
    } ]
  }
Vlad Berezan
  • 508
  • 1
  • 4
  • 6
  • 1
    That's the answer as I don't want to use the HashLocationStrategy in my WebApp. Thanks @Vlad – andreasonny83 May 07 '17 at 11:47
  • 3
    can anyone explain why does mapping every non-matching url to index.html can solve this issue? and it didn't work for me at all, it turns out that for every static asset I have, I got an index.html, i.e. cordova.js, main.css – Zhang Bruce Jan 23 '18 at 05:07
  • and what about if I have a server side rendered app and I need to point the `destanation` to the **firebase function**? – eagor Dec 02 '18 at 08:11
  • Does anyone have a link to some docs about this, please? Worked for me, but I'd like to know a little more about what's happening behind. And thanks! – Daniel Guzman Jul 16 '20 at 20:37
18

In your app.module.ts file just add following things:

declare

import { LocationStrategy, HashLocationStrategy} from '@angular/common';

and in providers add following

   @NgModule({
        declarations: [...],
        imports:[...],
        providers:[..,{ provide: LocationStrategy, useClass: HashLocationStrategy },..]
        ...,
    })

Hope this will solve your problem.

And if possible keep your Routes in separate file.

Cheers

The Hungry Dictator
  • 3,444
  • 5
  • 37
  • 53
  • This fixed my issue. To clarify, you are saying that in firebase hosting using angular js I need to use the URL fragment for the full path. https://MY-APP.firebaseapp.com/#/privacy-policy – Philip Brack Nov 17 '16 at 02:58
5

Open firebase.json

if you have this:

    "ignore": [
  "firebase.json",
  "**/.*",
  "**/node_modules/**"
]

remove the **/.* line

so you have this:

"ignore": [
  "firebase.json",
  "**/node_modules/**"
]

left me with this and worked:

    {
  "database": {
    "rules": "database.rules.json"
  },
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "hosting": {
    "public": "dist",
    "rewrites": [ {
      "source": "**",
      "destination": "/index.html"
    } ],
    "ignore": [
      "firebase.json",
      "**/node_modules/**"
    ]
  }
}
Michael Staples
  • 537
  • 7
  • 13
3

I am on Angular 8 and this worked for me

ng build --prod firebase deploy

Also my firebase.json file looks like below:

    {
        "hosting": {
         "public": "dist/crm",
         "ignore": [
            "firebase.json",
            "**/.*",
            "**/node_modules/**"
         ],
         "rewrites": [
          {
            "source": "**",
            "destination": "/index.html"
          }
        ]
      }
    }

In dist/crm, crm is the name of the project folder. I hope it helps.

debugmode
  • 936
  • 7
  • 13