How to translate MatPaginator
Tags: angular, typescript
Published: 2021-02-14 19:18:56

---
title: How to translate MatPaginator
published: true
date: 2021-02-12 00:00:00 UTC
tags: angular, typescript
canonical_url: https://www.mariokandut.com/how-to-translate-matpaginator-angular/
---

When building an Angular application often the **Material Design Components** from [Angular](https://material.angular.io/) are used. Many use cases require the application to be translated. There are plenty of different translation modules available. When you have tables with paginators in your application, it's getting a bit more complicated than just changing a string.

**MatPaginator** or `<mat-paginator>` provides navigation for paged information, typically used with a table.

Each paginator instance requires:

- The number of items per page (default set to 50)
- The total number of items being paged
- The current page index defaults to 0, but can be explicitly set via pageIndex.

The paginator displays a dropdown of page sizes for the user to choose from. The options for this dropdown can be set.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#one-translation-only)One translation only

Angular provides the `MatPaginatorIntl` so you can internationalize the labels, though if you only want to translate into one language, you can do it likes this:

```
this.paginator._intl.itemsPerPageLabel = 'Items pro Seite';
this.paginator._intl.nextPageLabel = 'Nächste';
this.paginator._intl.previousPageLabel = 'Vorherige';
```

The future-proof way would be to provide an own instance of `MatPaginatorIntl`.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#internationalization)Internationalization

The labels for the paginator can be customized by providing your own instance of `MatPaginatorIntl`.

This will allow you to change the following:

- The label for the length of each page.
- The range text displayed to the user.
- The tooltip messages on the navigation buttons.

Let's walk through an example with using [ngx-translate](https://github.com/ngx-translate/core).

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#1-create-injectable-class)1. Create Injectable Class

The class subscribes to language changes, also unsubscribes onDestroy, and updates the translations accordingly, for more details visit [Github - Angular Issue/Feature](https://github.com/angular/components/issues/5573).

```
import { Injectable, OnDestroy } from '@angular/core';
import { MatPaginatorIntl } from '@angular/material';
import { TranslateService } from '@ngx-translate/core';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class CustomMatPaginatorIntl extends MatPaginatorIntl
  implements OnDestroy {
  unsubscribe: Subject<void> = new Subject<void>();
  OF_LABEL = 'of';

  constructor(private translate: TranslateService) {
    super();

    this.translate.onLangChange
      .takeUntil(this.unsubscribe)
      .subscribe(() => {
        this.getAndInitTranslations();
      });

    this.getAndInitTranslations();
  }

  ngOnDestroy() {
    this.unsubscribe.next();
    this.unsubscribe.complete();
  }

  getAndInitTranslations() {
    this.translate
      .get([
        'PAGINATOR.ITEMS_PER_PAGE',
        'PAGINATOR.NEXT_PAGE',
        'PAGINATOR.PREVIOUS_PAGE',
        'PAGINATOR.OF_LABEL',
      ])
      .takeUntil(this.unsubscribe)
      .subscribe(translation => {
        this.itemsPerPageLabel =
          translation['PAGINATOR.ITEMS_PER_PAGE'];
        this.nextPageLabel = translation['PAGINATOR.NEXT_PAGE'];
        this.previousPageLabel =
          translation['PAGINATOR.PREVIOUS_PAGE'];
        this.OF_LABEL = translation['PAGINATOR.OF_LABEL'];
        this.changes.next();
      });
  }

  getRangeLabel = (
    page: number,
    pageSize: number,
    length: number,
  ) => {
    if (length === 0 || pageSize === 0) {
      return `0 ${this.OF_LABEL} ${length}`;
    }
    length = Math.max(length, 0);
    const startIndex = page * pageSize;
    const endIndex =
      startIndex < length
        ? Math.min(startIndex + pageSize, length)
        : startIndex + pageSize;
    return `${startIndex + 1} - ${endIndex} ${
      this.OF_LABEL
    } ${length}`;
  };
}
```

[💰: Start your cloud journey with $100 in free credits with DigitalOcean!](https://m.do.co/c/29f238135b61)

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#2-import--update-provider)2. Import & Update provider

Import and add the class in providers in your `app.module.ts`file.

```
import { CustomMatPaginatorIntl } from './shared/custom-mat-paginator-intl';

providers: [
  {
    provide: MatPaginatorIntl,
    useClass: CustomMatPaginatorIntl,
  },
];
```

### [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#3-done)3. Done

🎉🎉🎉 **Congratulations!** 🎉🎉🎉

You have successfully internationalized `MatPaginator`.

## [<svg aria-hidden="true" focusable="false" height="16" version="1.1" viewbox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>](#tldr)TL;DR

Material Design Components from Angular make a lot of things easier, unfortunately translating the paginator is not one of them. To provide a translation you have to:

- Create an injectable class, which listens to language changes and updates translations
- Provide translation in `app.module`

Thanks for reading and if you have any **questions** , use the **comment** function or **send me a message** **[@mariokandut](https://www.twitter.com/mariokandut)**. If you want to know more about **[Angular](https://www.mariokandut.com/tags/angular)**, have a look at these [Angular Tutorials](https://www.mariokandut.com/tags/angular).

**References (and Big thanks):** [Google - Angular](https://angular.io/docs),[Konrad Klimczak](https://medium.com/front-dev/translate-your-matpaginator-with-ngx-translate-and-stay-reactive-4c7b145cae9),[Github - Angular Issue/Feature](https://github.com/angular/components/issues/5573)