Build a language detection app with Chrome’s Built-in AI in Angular
December 31, 2024

Build a language detection app with Chrome’s Built-in AI in Angular

In this article, I describe how to build a simple language detection application natively using Chrome’s built-in language detection API and Angular. First, the Angular application calls an API to create a language detector and uses it to detect the language code of the input text. It then calls a helper function to map language codes to language names.

The cost is zero as the application does not require LLM from any provider.

It’s a happy path when users use Chrome Dev or Chrome Canary. If the user is using a non-Chrome or older Chrome browser, there should be a fallback implementation, such as calling Gemma or Gemini on Vertex AI to return the language name of the text.


Install Gemini Nano on Chrome

Update Chrome Dev/Canary to the latest version. As of this writing, the latest version of Chrome Canary is 133.

Please refer to this section to sign up for the early preview program of Chrome’s built-in AI.
https://developer.chrome.com/docs/ai/built-in#get_an_early_preview

Please refer to this section to enable Gemini Nano on Chrome and download the model. https://developer.chrome.com/docs/ai/get-started#use_apis_on_localhost


Install the language detection API on Chrome

  1. Go to chrome://flags/#language-detection-api.
  2. Select Enable.
  3. Click Restart or restart Chrome.


Scaffolding Angular applications

ng new language-detector-demo
Enter full screen mode

Exit full screen mode


Install dependencies

npm i -save-exact -save-dev @types/dom-chromium-ai
Enter full screen mode

Exit full screen mode

This dependency provides TypeScript types for all Chrome’s built-in APIs. Therefore, developers can use TypeScript to write elegant code to build AI applications.

In main.ts, add a reference tag to point to the package’s type definition file.

// main.ts

/// 
Enter full screen mode

Exit full screen mode


boot language detector

import { InjectionToken } from '@angular/core';

export const AI_LANGUAGE_DETECTION_API_TOKEN = new InjectionToken<AILanguageDetectorFactory | undefined>('AI_LANGUAGE_DETECTION_API_TOKEN');
Enter full screen mode

Exit full screen mode

import { AI_LANGUAGE_DETECTION_API_TOKEN } from '../constants/core.constant';

export function provideAILanguageDetectionAPI(): EnvironmentProviders {
    return makeEnvironmentProviders([
        {
            provide: AI_LANGUAGE_DETECTION_API_TOKEN,
            useFactory: () => {
                const platformId = inject(PLATFORM_ID);
                const objWindow = isPlatformBrowser(platformId) ? window : undefined;
                return objWindow?.ai?.languageDetector ? objWindow?.ai?.languageDetector : undefined;
            },
        }
    ]);
}
Enter full screen mode

Exit full screen mode

I defined an environment provider to return languageDetector In the example window.ai namespace. When code is injected AI_LANGUAGE_DETECTION_API_TOKEN After the token, they can access the language detection API and call its methods to detect the language code.

// app.config.ts

export const appConfig: ApplicationConfig = {
  providers: [
    provideAILanguageDetectionAPI()
  ]
};
Enter full screen mode

Exit full screen mode

In the application configuration, provideAILanguageDetectorAPI is imported into the providers array.


Verify browser version and API availability

Chrome’s built-in AI is experimental, but the language detection API is supported in Chrome version 129 and above. Therefore, I implemented validation logic to ensure that the API is available before displaying the UI so the user can enter text.

Validation rules include:

  1. The browser is Chrome
  2. Browser version is at least 129
  3. The ai object is located in the window namespace
  4. The status of the language detection API is clear at a glance
export async function checkChromeBuiltInAI(): Promise<string> {
  if (!isChromeBrowser()) {
     throw new Error(ERROR_CODES.UNSUPPORTED_BROWSER);
  }

  if (getChromVersion() < CHROME_VERSION) {
     throw new Error(ERROR_CODES.OLD_BROSWER);
  }

  const apiName = 'Language Detection API';
  if (!('ai' in globalThis)) {
     throw new Error(ERROR_CODES.NO_API);
  }

  const languageDetector = inject(AI_LANGUAGE_DETECTION_API_TOKEN);
  const status = (await languageDetector?.capabilities())?.available;
  if (!status) {
     throw new Error(ERROR_CODES.NO_API);
  } else if (status === 'after-download') {
     throw new Error(ERROR_CODES.AFTER_DOWNLOAD);
  } else if (status === 'no') {
     throw new Error(ERROR_CODES.NO_GEMINI_NANO);
  }

  return '';
}
Enter full screen mode

Exit full screen mode

this checkChromeBuiltInAI Function ensures that the language detection API is defined and available for use. If the check fails, the function throws an error. Otherwise, it returns an empty string.

export function isLanguageDetectionAPISupported(): Observable<string> {
   return from(checkChromeBuiltInAI()).pipe(
      catchError(
         (e) => {
            console.error(e);
            return of(e instanceof Error ? e.message : 'unknown');
         }
      )
   );
}
Enter full screen mode

Exit full screen mode

this isLanguageDetectionAPISupported The function captures errors and returns an Observable of error messages.


Show AI components

@Component({
    selector: 'app-detect-ai',
    imports: [LanguageDetectionComponent],
    template: `
    
@let error = hasCapability(); @if (!error) { } @else if (error !== 'unknown') { {{ error }} }
`
}) export class DetectAIComponent { hasCapability = toSignal(isLanguageDetectionAPISupported(), { initialValue: '' }); }
Enter full screen mode

Exit full screen mode

this DetectAIComponent present LanguageDetectionComponent There is no room for error. Otherwise, it will display an error message in the error signal.

@Component({
    selector: 'app-language-detection',
    imports: [FormsModule, LanguageDetectionResultComponent],
    template: `
    

Input text: