or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

caching.mdconfiguration.mddetection.mddetectors.mdindex.md
tile.json

detectors.mddocs/

Detector Modules

Eight specialized detector modules for different browser APIs and storage mechanisms. Each detector implements a consistent interface for language lookup and optional caching, providing flexibility to extend the detection system with custom implementations.

Capabilities

Custom Detector Interface

Interface that all detector modules must implement for integration with the detection system.

interface CustomDetector {
  /** Unique name for the detector */
  name: string;
  
  /** 
   * Language detection implementation
   * @param options - Configuration options from DetectorOptions
   * @returns Detected language code(s) or undefined if none found
   */
  lookup(options: DetectorOptions): string | string[] | undefined;
  
  /** 
   * Optional caching implementation
   * @param lng - Language code to cache
   * @param options - Configuration options from DetectorOptions
   */
  cacheUserLanguage?(lng: string, options: DetectorOptions): void;
}

Cookie Detector

Detects language from browser cookies with support for reading and writing cookie values.

// Built-in detector: 'cookie'
interface CookieDetector {
  name: 'cookie';
  lookup(options: DetectorOptions): string | undefined;
  cacheUserLanguage(lng: string, options: DetectorOptions): void;
}

How it works:

  • Lookup: Reads cookie value using
    options.lookupCookie
    (default: 'i18next')
  • Caching: Sets cookie with language value using
    options.cookieMinutes
    ,
    options.cookieDomain
    , and
    options.cookieOptions
  • Browser Compatibility: Safely handles environments where
    document.cookie
    access throws exceptions

Usage Examples:

// Configure cookie detection
const options = {
  lookupCookie: 'user_language',
  cookieMinutes: 60 * 24 * 30, // 30 days
  cookieDomain: '.example.com',
  cookieOptions: {
    secure: true,
    sameSite: 'strict'
  }
};

// Manual cookie detection
detector.detect(['cookie']); // Only use cookie detection

QueryString Detector

Detects language from URL query parameters, supporting both standard query strings and hash-based parameters.

// Built-in detector: 'querystring'
interface QueryStringDetector {
  name: 'querystring';
  lookup(options: DetectorOptions): string | undefined;
}

How it works:

  • Lookup: Parses URL query string using
    options.lookupQuerystring
    (default: 'lng')
  • Fallback: If no query string exists, checks
    window.location.hash
    for query parameters
  • Example URLs:
    ?lng=en
    ,
    #/page?lng=en
    ,
    ?lang=fr-CA

Usage Examples:

// Configure querystring detection
const options = {
  lookupQuerystring: 'lang' // Look for ?lang=en instead of ?lng=en
};

// URLs that would be detected:
// https://example.com?lang=en -> 'en'
// https://example.com#/route?lang=fr -> 'fr'
// https://example.com/page?lang=zh-CN -> 'zh-CN'

LocalStorage Detector

Detects and caches language in browser localStorage with availability checking.

// Built-in detector: 'localStorage'
interface LocalStorageDetector {
  name: 'localStorage';
  lookup(options: DetectorOptions): string | undefined;
  cacheUserLanguage(lng: string, options: DetectorOptions): void;
}

How it works:

  • Lookup: Reads localStorage value using
    options.lookupLocalStorage
    (default: 'i18nextLng')
  • Caching: Sets localStorage value if localStorage is available
  • Availability Check: Tests localStorage accessibility before use

Usage Examples:

// Configure localStorage detection
const options = {
  lookupLocalStorage: 'app_language',
  caches: ['localStorage'] // Enable caching to localStorage
};

// localStorage key will be 'app_language'
// Value persists across browser sessions

SessionStorage Detector

Detects and caches language in browser sessionStorage with availability checking.

// Built-in detector: 'sessionStorage'
interface SessionStorageDetector {
  name: 'sessionStorage';
  lookup(options: DetectorOptions): string | undefined;
  cacheUserLanguage(lng: string, options: DetectorOptions): void;
}

How it works:

  • Lookup: Reads sessionStorage value using
    options.lookupSessionStorage
    (default: 'i18nextLng')
  • Caching: Sets sessionStorage value if sessionStorage is available
  • Session Scope: Value persists only for the current browser session

Usage Examples:

// Configure sessionStorage detection
const options = {
  lookupSessionStorage: 'session_lang',
  caches: ['sessionStorage'] // Enable caching to sessionStorage
};

// sessionStorage key will be 'session_lang'
// Value cleared when browser tab is closed

Navigator Detector

Detects language from browser navigator object, supporting multiple browser language APIs.

// Built-in detector: 'navigator'
interface NavigatorDetector {
  name: 'navigator';
  lookup(options: DetectorOptions): string[] | undefined;
}

How it works:

  • Multiple Sources: Checks
    navigator.languages
    ,
    navigator.userLanguage
    , and
    navigator.language
  • Priority Order: Returns array with all available languages in priority order
  • Browser Compatibility: Safely handles missing navigator APIs

Usage Examples:

// Navigator detection returns language arrays
const detected = detector.detect(['navigator']);
// Example result: ['en-US', 'en', 'fr']

// Handles different browser implementations:
// Chrome: navigator.languages = ['en-US', 'en']
// IE: navigator.userLanguage = 'en-US'
// Safari: navigator.language = 'en-US'

HTML Tag Detector

Detects language from HTML lang attribute on specified elements.

// Built-in detector: 'htmlTag'
interface HtmlTagDetector {
  name: 'htmlTag';
  lookup(options: DetectorOptions): string | undefined;
}

How it works:

  • Element Source: Reads
    lang
    attribute from
    options.htmlTag
    or
    document.documentElement
  • Server-Side Compatible: Works in server-side rendering environments
  • DOM Safety: Safely handles missing DOM APIs

Usage Examples:

// Use default document element
const defaultOptions = {}; // Uses document.documentElement

// Use specific element
const customOptions = {
  htmlTag: document.querySelector('#app')
};

// Disable HTML tag detection
const disabledOptions = {
  htmlTag: null
};

// Example HTML:
// <html lang="en-US"> -> 'en-US'
// <div id="app" lang="fr"> -> 'fr' (if configured)

Path Detector

Detects language from URL path segments using configurable indexing.

// Built-in detector: 'path'
interface PathDetector {
  name: 'path';
  lookup(options: DetectorOptions): string | undefined;
}

How it works:

  • Path Parsing: Extracts language from
    window.location.pathname
    using regex
  • Index Selection: Uses
    options.lookupFromPathIndex
    to select which path segment
  • Pattern Matching: Matches
    /language-code/
    patterns in the URL path

Usage Examples:

// Configure path detection
const options = {
  lookupFromPathIndex: 0 // Use first path segment
};

// Example URLs:
// /en/home -> 'en'
// /fr-CA/products -> 'fr-CA'
// /zh/about/contact -> 'zh'

// Use second segment
const secondSegmentOptions = {
  lookupFromPathIndex: 1
};

// /app/en/dashboard -> 'en' (second segment)

Subdomain Detector

Detects language from hostname subdomains using pattern matching and indexing.

// Built-in detector: 'subdomain'
interface SubdomainDetector {
  name: 'subdomain';
  lookup(options: DetectorOptions): string | undefined;
}

How it works:

  • Hostname Parsing: Extracts language from
    window.location.hostname
    using regex
  • Pattern Matching: Matches subdomain patterns like
    en.example.com
    or
    fr.localhost
  • Index Selection: Uses
    options.lookupFromSubdomainIndex
    to select subdomain position

Usage Examples:

// Configure subdomain detection
const options = {
  lookupFromSubdomainIndex: 0 // Use first subdomain
};

// Example hostnames:
// en.example.com -> 'en'
// fr.myapp.localhost -> 'fr'
// de.api.service.com -> 'de' (first subdomain)

// Use different subdomain position
const secondSubdomainOptions = {
  lookupFromSubdomainIndex: 1
};

// api.en.example.com -> 'en' (second subdomain)

Creating Custom Detectors

Implement the

CustomDetector
interface to create custom detection methods:

// Example: Detect language from user API preferences
const apiDetector: CustomDetector = {
  name: 'userApi',
  
  async lookup(options) {
    try {
      const response = await fetch('/api/user/preferences');
      const data = await response.json();
      return data.language;
    } catch (error) {
      return undefined; // Return undefined on error
    }
  },
  
  async cacheUserLanguage(lng, options) {
    try {
      await fetch('/api/user/preferences', {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ language: lng })
      });
    } catch (error) {
      // Handle error silently
    }
  }
};

// Add to detector
detector.addDetector(apiDetector);

// Use in detection order
detector.init(null, {
  order: ['userApi', 'cookie', 'navigator']
});

Error Handling

All built-in detectors are designed to fail gracefully:

  • Missing APIs: Return
    undefined
    when browser APIs are not available
  • Storage Errors: Skip storage operations if localStorage/sessionStorage throw exceptions
  • DOM Errors: Handle missing
    document
    or
    window
    objects in server-side environments
  • Network Errors: Custom detectors should catch and handle network failures
  • Type Safety: Always return
    string
    ,
    string[]
    , or
    undefined
    from lookup methods