How to deploy angular app on GitHub Pages for free

In this blog post, we are going to discuss about “how we can deploy an angular app on GitHub Pages for free”

To discuss further, lets create a angular application using the Angular CLI. You can checkout one of our detailed post on how to create angular app using CLI here.

Create an angular application using angular CLI

The flow is we are going to generate an angular app using angular CLI. The CLI will generate us a sample application and we will push that boilerplate into GitHub with a new repo.

And then we will look into the steps to deploy that application in github pages.

Create GitHub Repository

I’m going to create an repository with a name “angular-hosting-demo”

Github Repo

Once I create repo, I’m going to push all codes here.

https://github.com/PandiyanCool/angular-hosting-demo

New application using Angular CLI

By generating following after installing all the necessary tools.

ng new <name> [options]

ng new angular-hosting-demo

It will generate an application with following folder structure.

File structure

Verify whether application is building and showing output using following command

ng serve

And it will show us the following output

localhost app

Now into action

For this we are going to install an npm package.

https://www.npmjs.com/package/angular-cli-ghpages

Add angular-cli-ghpages to your project

Run the following command to add angular-cli-ghpages

ng add angular-cli-ghpages

You have run the above from the home directory or root directory of your project.

It will update the angular.json file in your repository.

Now commit all your changes to remote branch.

Deploy your project to GitHub pages

Deploy your project to GitHub pages with all default settings. Your project will be automatically built in production mode.

ng deploy --base-href=/<repositoryname>/

Please be aware of the –base-href option. It is necessary when your project will be deployed to a non-root folder.

In our case, we will run the following command to deploy the application with repo name as bas-href value

ng deploy --base-href=angular-hosting-demo

And this built code will uploaded into separate branch called gh-pages

https://github.com/PandiyanCool/angular-hosting-demo/tree/gh-pages

And it will have runtime files as below

deployed code

And base-href would have details of repository name

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>AngularHostingDemo</title>
  <base href="angular-hosting-demo">  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="styles.09e2c710755c8867a460.css"></head>
<body>
  <app-root></app-root>
<script src="runtime-es2015.0dae8cbc97194c7caed4.js" type="module"></script><script src="runtime-es5.0dae8cbc97194c7caed4.js" nomodule defer></script><script src="polyfills-es5.177e85a9724683782539.js" nomodule defer></script><script src="polyfills-es2015.f332a089ad1600448873.js" type="module"></script><script src="main-es2015.48f00976eb36d615f1e8.js" type="module"></script><script src="main-es5.48f00976eb36d615f1e8.js" nomodule defer></script></body>
</html>

https://github.com/PandiyanCool/angular-hosting-demo/blob/gh-pages/index.html

Access deployed site

To get the URL, you can visit the settings page. It will provide the details of hosted application under github pages tab

Now, we can access the deployed site in the following URL

https://pandiyancool.github.io/angular-hosting-demo/

Thats it!

Give it a try, and leave your feedbacks in comment section below.

Internationalization with angular

Internationalization is the process of designing and preparing your app to be usable in different languages.

Localization is the process of translating your internationalized app into specific languages for particular locales.

Internalization in angular

Angular simplifies the following aspects of internationalization:

  • Displaying dates, numbers, percentages, and currencies in a local format.
  • Preparing text in component templates for translation.
  • Handling plural forms of words.
  • Handling alternative text.

You can find the official technical documentation of the current major version of angular here.

What’s new in angular 9?

Currently, Angular 9 is in the release candidate version.

Angular provides the option to explore the upcoming version to the users.

The official documentation of next-gen release can be found here.

Earlier to angular 9, let’s say angular less than version 8.

The internalization implementation isn’t straight forward or easy to go implementation.

npm tools

So, We need the support of a third party plugin to achieve the concepts. Popular plugins for il8n(Internationalization) are

However, angular 9 brings the power of il8n in it and makes it easy to implement and use.

How to add il8n?

Now, the angular CLI supports the option to add the localize option in our project

ng add @angular/localize

Once we have run the above command in our project, the CLI will add necessary dependencies to the project.

And it adds following the entry into the polyfills.ts

import ‘@angular/localize/init’

Then we need to configure the angular.json with multiple locale files as below

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1, 
  "newProjectRoot": "projects",
  "projects": {
    "angular-localize": {
      "projectType": "application",
      
      "i18n": {
        "locales": {
          "fr":"messages.fr.xlf" ,
          "tm": "messages.tm.xlf"
        }
      },
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/angular-localize",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "aot": true,
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "buildOptimizer": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb",
                  "maximumError": "10kb"
                }
              ]
            },
            "fr": {
              "localize": ["fr"]
            },
            "tm": {
              "localize": ["tm"]
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "angular-localize:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "angular-localize:build:production"
            },
            "fr": {
              "browserTarget": "angular-localize:build:fr"
            },
            "tm": {
              "browserTarget": "angular-localize:build:tm"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "angular-localize:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "tsconfig.app.json",
              "tsconfig.spec.json",
              "e2e/tsconfig.json"
            ],
            "exclude": [
              "**/node_modules/**"
            ]
          }
        },
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "angular-localize:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "angular-localize:serve:production"
            }
          }
        }
      }
    }},
  "defaultProject": "angular-localize"
}

The angular package provides an option called $localize which can be used in the component

export class AppComponent {
  title = $localize`angular-localize`;
}

Adding language files

When the application process $localize, it will look for the translated or il8n text the target text in the locale file.

The locale files are configured in the angular.json already.

Let’s explore that file now.

<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
  <file source-language="en-US" datatype="plaintext" original="ng2.template">
    <body>
    <trans-unit id="8298328021206315701">
  <source>angular-localize</source>
  <target>Bonjour</target>
</trans-unit>
    </body>
  </file>
</xliff>
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
  <file source-language="en-US" datatype="plaintext" original="ng2.template">
    <body>
    <trans-unit id="3902961887793684628">
  <source>hello</source>
  <target>வணக்கம்</target>
</trans-unit>
    </body>
  </file>
</xliff>

Here, we two files to support two locales. And it has been stored in xlf format.

XLF is an XML localization file format.

Running application

ng serve

The above picture shows the default text from the application.

Now let’s run the custom command to point it to french language and see the output.

ng serve –configuration=fr

Therefore the word angular-localise is changed into Bonjour based on the language we have configured.

In conclusion, we can configure N number of languages and host it based on needs.

Disclaimer

Finally, Few things need to be done while experimenting with the above code.

Since this package is supported in angular 9 we need to maintain a matching node environment to experiment with the code. And you can find the entire source code in this GitHub Repository.

Happy Coding!