How to deploy a multi-language Angular 10 app to Google Cloud using Firebase

From a post before I wrote about how you can implement different languages into your language with the help of Angular’s i18n internationalization system. That means your application can be built and have multiple folders which are the translated version of the app. In this example I have Japanese and the default English from previous post. What we want to do here is take use of the translations we have already made. Before we could easily switch between the languages with the help of various configurations by using the serve command, however, what if we want to have the languages changable depending on what URL is being used? We will make it possible to have the English version if the user visit en in the URL, or ja in the URL for Japanese version. Note that English have no actual translations from a translation file because this is the default language To accomplish our goal we must deploy all the languages folders and have the language URL bound to each language version. Let’s go through what needs to be done to accomplish that.

First we must make sure that sourceLocale is set to en-US and we have locales like this in our anguar.json file.

I currently have this under my project app name:

"i18n": {
        "sourceLocale": "en-US",
        "locales": {
          "ja": "src/locale/messages.ja.xlf"
        }
      }, [...]

Then I will check so that we can still build and serve it by running ng server –configuration=”ja” which it does. Remember, from the previous post all of this has already been set up.

Great, we know we have Japanese language working. Let’s set up the possibility to deploy to Google Cloud, or well, to Firebase. For the usual Google Cloud deploys we would need to have a .yaml file, but in this case we need a firebase.json since this is Firebase we are working with. To get things ready we need to initialize Firebase.

Init firebase

Since I don’t have Firebase initialized already, I’ll do it by typing this.

firebase init

Notice I am in my root project folder when initializing Firebase, I choose hosting because that’s what I am interested in only for now and also rewrite URLs to index. I already had a default project so didn’t need to choose. If you don’t have an project yet simply create one at console firebase. Now we could try firebase deploy but then we would see this beautiful screen:

Anyways, it means it is working at least! We can open up firebase.json and see that it is deploying a newly created public folder which contains a index.html Firebase created. Let’s not go with that and deploy our own app! I am going to go ahead and say public is equals to our ja folder (my Japanese version folder) to see if the app will show the translations just to verify. If you’re wondering why schoolUi is appearing everywhere, it is just the name of my app I am using currently. So this is the current settings in the firebase.json.

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

Save. Build a prod build if you haven’t already.

ng build --prod --localize

Now do the deploy with firebase deploy.

firebase deploy

Crazy how fast it is to deploy (specially with Firebase), let’s see what happen by opening up the URL we got printed out in the terminal if successfully deployed.

First I thought something was wrong since I only saw the index.html from before but with a web browser refresh I can now see my app in the Japanese version exactly what we wanted! Alright so next challenge is to deploy all folders and have a index.html file linking to each language URLs. Let’s modify our host property so we can use the app in more languages. If you want to go into more detail you can see information about this here.

I also happen to notice a thing that could be improved which is in the angular.json file, that en-US should be named en there instead since that’s what we want the URL to be too. So let’s build it again.

angular.json is now

      "i18n": {
        "sourceLocale": {
          "code": "en"
        },
        "locales": {
          "ja": {
            "translation": "src/locale/messages.ja.xlf"
          }
        }
      },

Let’s build a prod build:

ng build --prod --localize.

We should have a folder of en and ja. Great, now I edited the firebase.json file to look like this. A lot of things happening here but hopefully I’ll make myself clear.

{
  "hosting": {
    "public": "./dist/schooUi",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "/ja/**",
        "destination": "/ja/index.html"
      },
      {
        "source": "/en/**",
        "destination": "/en/index.html"
      }
    ],
    "i18n": {
      "root": "/"
    }
  }
}

Key is is that public folder is set to the folder which contains all of the languages, in my case it contains both en and ja and then we set i18n root to the same folder with the forward slash.

We deploy now

firebase deploy

We can now visit https://x.web.app/en/ for English and https://x.web.app/ja/ for Japanese. Default will be https://x.web.app/en/. And there we go, we got support for multiple languages in different URLs.

5 1 vote
Article rating
Subscribe
Notify of
guest

3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
makois

Thank you for this awesome helpful article!
Well, I have 2 questions.
1. In the official doc(https://firebase.google.com/docs/hosting/i18n-rewrites), Firebase seems to automatically move a user to the page which is according to Accept-Language value. Does your sample app do the same behavior?
2. Did you test this sample app on Firebase Emulator? And did it work fine, as same as on real Firebase hosting?
Best regards.

josh
Article rating :
     

Thanks so much for this write-up! First time trying to figure out i18n with Angular and Firebase and the Firebase documentation had me a little stumped, particularly around rewrites. Angular routing wasn’t working because of this and I spent so much time trying to figure it out. This helped me out in no time. Thanks again!