When you want to create a language system and add multiple languages to your Ionic APP you have various designs available, but in a simple APP, there are 2 major ones.

The first design is where the UI design and APP functionality remain the same for both languages, in this case, you can use some javascript objects for every component you have.
This design is suited when you want to have consistency and implies a bit less work.

The second option is to clone each of your components for every language and make an appropriate file structure.
This design works well when you want to have different functionality and UI depending on the language.

Of course, there is the possibility to mix between these two designs, but in this article, I will present a simple implementation of the second design.

First, you create can create an interface for your settings object, even though you don’t have any other settings in your app:

export interface SettingsObj {
    language: string
  }

I usually make a folder with all interfaces so in this case from the app.components.ts the import looks like this:

import { SettingsObj } from '../interfaces/SettingsInterface'

Secondly, I create two services one for handling the settings object and one for handling the languages:
File …settings.ts with SettingsService:

import { SettingsObj } from '../interfaces/SettingsInterface';
import {Injectable} from "@angular/core";

@Injectable()
export class SettingsService {
  constructor() {

  }

  public giveDefaultSertvice(): SettingsObj {
    let sRet:SettingsObj = {
       language:"RO",
    }
    return sRet;
  }
}

As you see this is mostly a dummy service with a method that is used in case we can’t get our settings object from DB.
File …language.ts with SettingsService:

import { Storage } from '@ionic/storage';
import { Injectable } from "@angular/core";

import { Events } from 'ionic-angular';

//Service
import { SettingsService } from './settings';
//Interface
import { SettingsObj } from '../interfaces/SettingsInterface'

@Injectable()
export class LanguageService {
  settings: SettingsObj;

  constructor(private events: Events,
    private storage: Storage,
    private settingsService: SettingsService) {

  }

  setLanguage(lang: string) {

    return Promise.resolve({
      then: (r) => {
        this.settings = this.settingsService.giveDefaultSertvice();
        this.settings.language = lang;
        console.log(lang);
        this.storage.set('settings', this.settings).then(
          _ => {
            this.events.publish('settings:language-change', this.settings)
            r('');
          }
        );

      }
    });
  }

}

The method setLanguage sets the language in the DB and emits after that an event so that the navigator knows the language has changed and change the view of the page.

Is important to notice that initially, we don’t know which language should we use for our user, so there are generally 3 obvious ways of dealing with that:
1 We choose for him and the user can change that later
2 We get the language from the system
3 We force the user to select a language when the app starts for the first time

In this case, we will use the third method, so basically will show a modal and the user will have to choose a preferred language.
First, in the main component, we will have something like this:

//...

rootPage:any = HomePage;

  pages: Array<{title: string, component: any}>;
  pagesEN:  Array<{title: string, component: any}>;

  changeLang(lang:string){
    this.langServ.setLanguage(lang);
  }

  openLanguageModal(){
    let contactModal = this.modalCtrl.create(LanguageModal);
     contactModal.present();
    }

//...

So all the pages used by the navigator will be in two arrays, as, in this case, we have two languages, the method openLanguageModal will be used to present the model for choosing the language for the first application use, we will check if is the first use like this in the constructor:

//...
  constructor(
  	private alertCtrl: AlertController,
    protected app: App,
    private keyboard: Keyboard,
    public platform: Platform,
    public menu: MenuController,
    public statusBar: StatusBar,
    public events: Events,
    public splashScreen: SplashScreen,
    private storage:Storage,
    private settingsService:SettingsService,
    private modalCtrl:ModalController,
    private langServ:LanguageService,

  ) {

            // First get the defalut Settings
            this.settings = this.settingsService.giveDefaultSertvice();

            // Get the setings from storage
             this.storage.get('settings').then( sOb => {
               if(sOb == null){
                  this.openLanguageModal();
               }else{
                this.settings = sOb;
                if(sOb.language == "EN"){
                  this.rootPage = HomePageEn;
                }

               }
             });

//...

If we can’t get the value from DB it means that this is the first use, so will show the modal otherwise we change the rootPage according to our language since this example has only two languages there is only a single check.

Also in the main component, we have to check if the language suddenly changed and also to populate the arrays with views for our languages.
To check if the language has changed we subscribe to an event:

//...
events.subscribe('settings:language-change', sOb => {
    this.settings = sOb;
    if(sOb.language == 'RO'){
      this.rootPage = HomePage;
    }else{
      this.rootPage = HomePageEn;
    }
    this.events.publish('page:open',this.rootPage );
} );
//...

As it’s seen when we detect a language change we will change the root page and then navigate on it, this is one of the simplest logic, as we do not care if the user was on a specific page, we do this for simplicity and also because the app pages/views aren’t fully mirrored so a page in a language may not have a correspondent in another.
The page arrays can be populated like this:

//...
    this.pages = [
      // Despre Noi
      { title: 'Prezentare', component: HomePage },
      { title: 'Conducere', component: ConducerePage },
      { title: 'Contact', component:ContactPage },
      { title: 'Rapoarte Activitate', component:RapoartePage },
      // Oferta Noastra
      { title: 'Oferta INPM', component:OfertaINPMPage },
      { title: 'Servicii in domeniul SSM', component:ServiciiSSMPage }

    ];

    this.pagesEN = [
      { title: 'Presentation', component: HomePageEn },
      { title: 'Management', component: ManagementPage },
      { title: 'What we offer', component:OfferPage },
      { title: 'Our OSH Services', component:OSHServicesPage }
    ];
//...

The title is in these arrays is used as the title of the page, we use that in the sidebar menu.
Furthermore, we can implement a simple language switcher presented in the menu sidebar:

Example of Language switcher in the template:

<!-- ... -->
       <!-- Language switcher -->
<div *ngIf="settings.language == 'RO'; else elseLangSwicth">

<div padding>
Schimba limba:
          <a style="font-size:2.1rem;" (click)="changeLang('EN')">
            <img style="width:2.1rem" src="assets/imgs/if_Jarvis-Island-Flag_32252.png"> Engleză
          </a></div>
         </div>
         <ng-template #elseLangSwicth>
<div padding>
Change Language:
          <a style="font-size:2.1rem;" (click)="changeLang('RO')">
            <img style="width:2.1rem" src="assets/imgs/if_Romania-Flag_32314.png"> Romanian
          </a>
        </div>
         </ng-template>
<!-- ... -->

Of course, you can visit the repo at URL if you want to see all the code: Link