Implement i18n using @ngx-translate in an Angular library with Storybook 6
Published: 2021-01-28 05:23:00

### ENV

Angular 10.0.4

Storybook 6.1.15

In this post, I'll describe the steps to generate an Angular component library with [Storybook](https://storybook.js.org/) that utilize [@ngx-translate](http://www.ngx-translate.com/) to provide i18n integration.

# Project setup

First let's generate a new workspace

```javascript
ng new my-workspace --create-application=false --style=scss 
```
Then let's generate an Angular library project inside the workspace.

```javascript
cd my-workspace
ng generate library my-lib
```
Install the required modules

```javascript
npm i @ngx-translate/core @ngx-translate/http-loader --save
```
Now, let's generate our sample component

```javascript
ng g c sample
```

And initialize storybook

```javascript
npx sb init
```

Edit sample.component.html

```javascript
<p>{{ label }}</p>
```

Edit sample.component.ts

```javascript
import { Component, OnInit, Input } from '@angular/core';

@Component({
  selector: 'lib-sample',
  templateUrl: './sample.component.html',
  styleUrls: ['./sample.component.css'],
})
export class SampleComponent implements OnInit {
  @Input() label = 'label';
  constructor() {}

  ngOnInit(): void {}
}
```
Add SampleComponent to exports section in my-lib.module.ts

```javascript
import { NgModule } from '@angular/core';
import { MyLibComponent } from './my-lib.component';
import { SampleComponent } from './sample/sample.component';

@NgModule({
  declarations: [MyLibComponent, SampleComponent],
  imports: [],
  exports: [MyLibComponent, SampleComponent],
})
export class MyLibModule {}
```

Add an i18n translation file and name it 'en.json' to stories/assets/i18n folder.

```javascript
{
  "LABEL": "Hello"
}
```

Create the I18nModule for the storybook setup inside stories/modules folder

```javascript
import { NgModule } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';

@NgModule()
export class I18nModule {
  constructor(translate: TranslateService) {
    translate.setDefaultLang('en');
    translate.use('en');
  }
}

```
Create sample component stories file 'stories/Sample.stories.ts'

```javascript
import { Story, Meta } from '@storybook/angular';
import { moduleMetadata } from '@storybook/angular';
import {
  FakeMissingTranslationHandler,
  MissingTranslationHandler,
  TranslateLoader,
  TranslateModule,
} from '@ngx-translate/core';
import { of } from 'rxjs';
import { I18nModule } from './modules/I18nModule';
import { MyLibModule } from '../projects/my-lib/src/lib/my-lib.module';
import { SampleComponent } from '../projects/my-lib/src/lib/sample/sample.component';

const staticTranslateLoader: TranslateLoader = {
  getTranslation(lang: string) {
    return of(require('./assets/i18n/en.json'));
  },
};

export default {
  title: 'Example/SampleComponent',
  decorators: [
    moduleMetadata({
      declarations: [],
      imports: [
        MyLibModule,
        I18nModule,
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader,
            useValue: staticTranslateLoader,
          },
          missingTranslationHandler: {
            provide: MissingTranslationHandler,
            useClass: FakeMissingTranslationHandler,
          },
        }),
      ],
    }),
  ],
  component: SampleComponent,
  argTypes: {},
} as Meta;

const Template: Story<SampleComponent> = (args: SampleComponent) => ({
  component: SampleComponent,
  props: args,
  template: `<lib-sample [label]="'LABEL' | translate"></lib-sample>`,
});

export const Default = Template.bind({});
Default.args = {};

```

Finally, we can run the command and see that i18n is working.

```javascript
npm run storybook
```