npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@libs-ui/services-translate

v0.2.357-4

Published

> Dịch vụ i18n cho Angular — mở rộng `@ngx-translate/core` với MessageFormat, global interpolation và tự động merge chuỗi dịch nội bộ.

Readme

@libs-ui/services-translate

Dịch vụ i18n cho Angular — mở rộng @ngx-translate/core với MessageFormat, global interpolation và tự động merge chuỗi dịch nội bộ.

Giới thiệu

@libs-ui/services-translate cung cấp LibsUiTranslateService — một lớp kế thừa từ TranslateService của @ngx-translate/core, tích hợp sẵn TranslateMessageFormatCompiler để xử lý cú pháp plural/select phức tạp. Service tự động merge các chuỗi dịch nội bộ của @libs-ui vào mọi ngôn ngữ, đồng thời cho phép thiết lập biến nội suy toàn cục áp dụng cho tất cả chuỗi dịch mà không cần truyền thủ công. Ngôn ngữ đang chọn được lưu tự động qua UtilsCache.

Tính năng

  • ✅ Kế thừa toàn bộ API của TranslateService — inject và dùng như bình thường
  • ✅ Hỗ trợ cú pháp MessageFormat — xử lý plural, select, ordinal
  • Global interpolation — thiết lập biến dùng chung cho toàn bộ chuỗi dịch (tên thương hiệu, hotline, ...)
  • ✅ Tự động merge chuỗi dịch nội bộ @libs-ui (hơn 100 key dùng cho các component UI)
  • ✅ Load file JSON qua HTTP với TranslateHttpLoader (đường dẫn tùy chỉnh)
  • ✅ Inject translation trực tiếp từ object (không cần file .json)
  • ✅ Lưu ngôn ngữ hiện tại vào UtilsCache (localStorage) khi gọi use()
  • ✅ Hỗ trợ hai ngôn ngữ: 'vi' (Tiếng Việt) và 'en' (English)
  • ✅ Safe fallback — instant()get() trả về key gốc nếu key rỗng/undefined

Khi nào sử dụng

  • Ứng dụng cần hỗ trợ đa ngôn ngữ và chuyển đổi ngôn ngữ tại runtime
  • Cần xử lý số ít/số nhiều (plural) hoặc chọn chuỗi theo giá trị (select) với cú pháp MessageFormat
  • Cần thiết lập biến toàn cục (tên thương hiệu, hotline, đơn vị tiền tệ) tự động xuất hiện trong mọi chuỗi dịch
  • Lib hoặc shared module cần inject chuỗi dịch từ code (object) thay vì phụ thuộc file JSON của từng app
  • Muốn các component @libs-ui hiển thị đúng ngôn ngữ mà không cần cấu hình thêm

Cài đặt

npm install @libs-ui/services-translate

Import

// Cấu hình providers (bắt buộc)
import { getConfigTranslate } from '@libs-ui/services-translate';

// Thiết lập biến nội suy toàn cục (tùy chọn)
import { setInterpolateParamDefault, getInterpolateParamDefault } from '@libs-ui/services-translate';

// Sử dụng trong component (inject qua @ngx-translate/core như bình thường)
import { TranslateService, TranslateModule } from '@ngx-translate/core';

Ví dụ sử dụng

1. Cấu hình providers trong app.config.ts

import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { getConfigTranslate } from '@libs-ui/services-translate';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(appRoutes),

    // Load từ /i18n/*.json (mặc định)
    getConfigTranslate(),
  ],
};

Cấu trúc thư mục file dịch mặc định (đặt trong public/):

public/
└── i18n/
    ├── vi.json
    └── en.json

2. Cấu hình đường dẫn tùy chỉnh

import { ApplicationConfig } from '@angular/core';
import { getConfigTranslate } from '@libs-ui/services-translate';

export const appConfig: ApplicationConfig = {
  providers: [
    // Load từ /assets/translations/*.json
    getConfigTranslate('/assets/translations/'),
  ],
};

3. Khởi tạo ngôn ngữ và inject translation từ object

import { Component, inject, OnInit } from '@angular/core';
import { TranslateModule, TranslateService } from '@ngx-translate/core';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [TranslateModule],
  template: `
    <span>{{ 'i18n_search' | translate }}</span>
    <span>{{ 'i18n_greeting' | translate: { name: 'Admin' } }}</span>
  `,
})
export class AppComponent implements OnInit {
  private readonly translate = inject(TranslateService);

  ngOnInit(): void {
    // Inject translation từ object (không cần file .json)
    this.translate.setTranslation('vi', {
      i18n_greeting: 'Xin chào, {name}!',
      i18n_welcome: 'Chào mừng đến với hệ thống',
    }, true); // true = merge, không ghi đè key có sẵn

    this.translate.setTranslation('en', {
      i18n_greeting: 'Hello, {name}!',
      i18n_welcome: 'Welcome to the system',
    }, true);

    // Đặt ngôn ngữ mặc định
    this.translate.use('vi');
  }
}

4. Chuyển đổi ngôn ngữ runtime

import { Component, inject } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { TYPE_LANGUAGE_SUPPORT } from '@libs-ui/interfaces-types';

@Component({
  selector: 'app-language-switcher',
  standalone: true,
  template: `
    <button (click)="handlerSwitchLang('vi')">Tiếng Việt</button>
    <button (click)="handlerSwitchLang('en')">English</button>
  `,
})
export class LanguageSwitcherComponent {
  private readonly translate = inject(TranslateService);

  handlerSwitchLang(event: Event, lang: TYPE_LANGUAGE_SUPPORT): void {
    event.stopPropagation();
    this.translate.use(lang);
    // Ngôn ngữ được tự động lưu vào UtilsCache (localStorage)
  }
}

5. Dùng instant()get() trong TypeScript

import { Component, inject } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { DestroyRef } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';

@Component({
  selector: 'app-notification',
  standalone: true,
  template: '',
})
export class NotificationComponent {
  private readonly translate = inject(TranslateService);
  private readonly destroyRef = inject(DestroyRef);

  // Đồng bộ (sync) — dùng khi translations đã được load xong
  getLabel(): string {
    return this.translate.instant('i18n_save');
    // Kết quả: 'Lưu' (vi) hoặc 'Save' (en)
  }

  // Với interpolation params
  getErrorMessage(maxLength: number): string {
    return this.translate.instant('i18n_message_error_input_max_length', { number: maxLength });
    // Kết quả: 'Độ dài tối đa 100 kí tự'
  }

  // Bất đồng bộ (async) — tự động cập nhật khi đổi ngôn ngữ
  getReactiveLabel(): void {
    this.translate.get('i18n_search')
      .pipe(takeUntilDestroyed(this.destroyRef))
      .subscribe((label: string) => {
        console.log(label);
      });
  }
}

6. Global Interpolation — biến dùng chung cho toàn bộ chuỗi dịch

// app.component.ts hoặc main.ts
import { setInterpolateParamDefault } from '@libs-ui/services-translate';

// Đặt một lần — áp dụng tự động cho TẤT CẢ chuỗi dịch
setInterpolateParamDefault({
  brand: 'Mobio CRM',
  hotline: '1900 1234',
  currency: 'VNĐ',
});

Trong file dịch JSON, dùng biến global trực tiếp:

{
  "i18n_contact_us": "Liên hệ {brand} qua hotline {hotline}",
  "i18n_price_unit": "Đơn vị: {currency}"
}

Trong template — không cần truyền params:

<span>{{ 'i18n_contact_us' | translate }}</span>
<!-- Kết quả: "Liên hệ Mobio CRM qua hotline 1900 1234" -->

7. MessageFormat — Plural và Select

File dịch vi.json:

{
  "i18n_user_count": "Có {value} {value,plural, =0 {người dùng} =1 {người dùng} other {người dùng}}",
  "i18n_status_display": "Trạng thái: {status,select, active {Đang hoạt động} inactive {Không hoạt động} other {Không xác định}}"
}

File dịch en.json:

{
  "i18n_user_count": "{value} {value,plural, =0 {user} =1 {user} other {users}} total",
  "i18n_status_display": "Status: {status,select, active {Active} inactive {Inactive} other {Unknown}}"
}

Trong template:

<!-- Plural -->
<span>{{ 'i18n_user_count' | translate: { value: 5 } }}</span>
<!-- Kết quả (vi): "Có 5 người dùng" -->

<!-- Select -->
<span>{{ 'i18n_status_display' | translate: { status: 'active' } }}</span>
<!-- Kết quả (vi): "Trạng thái: Đang hoạt động" -->

Methods

| Method | Signature | Mô tả | |---|---|---| | getConfigTranslate | (linkFileI18n?: string) => Provider[] | Trả về mảng providers để cấu hình i18n toàn app. linkFileI18n là đường dẫn thư mục chứa file dịch (mặc định /i18n/). | | setInterpolateParamDefault | (interpolate: Record<string, string>) => void | Thiết lập biến nội suy toàn cục áp dụng tự động cho mọi chuỗi dịch khi gọi instant(), get(), getParsedResult(). | | getInterpolateParamDefault | () => Record<string, string> | Lấy giá trị biến nội suy toàn cục hiện tại. | | instant | (key: string \| string[], params?) => string \| any | Dịch đồng bộ. Trả về key nếu key rỗng (thay vì throw lỗi). Tự động merge interpolateParamDefault. | | get | (key: string \| string[], params?) => Observable<string \| any> | Dịch bất đồng bộ, tự cập nhật khi đổi ngôn ngữ. Trả về of(key) nếu key rỗng. | | use | (lang: TYPE_LANGUAGE_SUPPORT) => Observable<any> | Chuyển ngôn ngữ, tự động merge chuỗi dịch nội bộ @libs-ui và lưu vào UtilsCache. |

Types

import { TYPE_LANGUAGE_SUPPORT } from '@libs-ui/interfaces-types';
// TYPE_LANGUAGE_SUPPORT = 'vi' | 'en'

TranslateProviderConfig — DI token config, được xuất để sử dụng khi cần override provider thủ công:

import { TranslateProviderConfig } from '@libs-ui/services-translate';

Chuỗi dịch nội bộ @libs-ui

LibsUiTranslateService tự động merge hơn 100 key i18n nội bộ dành cho các component @libs-ui (bảng phân trang, upload file, date picker, rich text editor, ...). Các key này được inject khi gọi use() và chỉ điền vào nếu app chưa có sẵn key đó (merge, không ghi đè).

Một số key tiêu biểu:

| Key | vi | en | |---|---|---| | i18n_search | Tìm kiếm | Search | | i18n_save | Lưu | Save | | i18n_cancel | Hủy bỏ | Cancel | | i18n_no_data | Không có dữ liệu | No data | | i18n_add_new | Thêm mới | Add new | | i18n_delete | Xoá | Delete | | i18n_valid_empty_message | Trường thông tin không được phép để trống | This field is required | | i18n_no_result | Không có kết quả | No result |

Lưu ý quan trọng

⚠️ Gọi getConfigTranslate() trong app.config.ts: Bắt buộc cấu hình provider ở cấp app root. KHÔNG gọi trong @NgModule hay lazy feature module.

⚠️ setInterpolateParamDefault() phải gọi trước use(): Biến global chỉ có hiệu lực với các lần dịch sau khi được thiết lập. Nên gọi trong AppComponent.ngOnInit() hoặc main.ts.

⚠️ instant() chỉ hoạt động sau khi translations đã load: Nếu gọi quá sớm (trước khi file JSON load xong), instant() trả về key gốc. Dùng get() (Observable) để đảm bảo luôn có giá trị đúng.

⚠️ Không cần inject LibsUiTranslateService trực tiếp: Service được cung cấp qua DI token của TranslateService. Inject bình thường bằng inject(TranslateService) — Angular sẽ resolve ra LibsUiTranslateService.

⚠️ setTranslation(lang, data, true) — tham số true bắt buộc khi merge: Không truyền true sẽ ghi đè toàn bộ translations đã có cho ngôn ngữ đó, bao gồm cả các key nội bộ của @libs-ui.

Demo

npx nx serve core-ui

Truy cập: http://localhost:4500/services/translate