Skip to main content

LanguagesClient

The LanguagesClient class provides methods for fetching language data from the YouVersion Platform API. It returns information about supported languages, including BCP 47 language codes, scripts, country associations, and display names.

Constructor

import { ApiClient, LanguagesClient } from '@youversion/platform-core';

const apiClient = new ApiClient({ appKey: 'your-app-key' });
const languagesClient = new LanguagesClient(apiClient);
client
ApiClient
required
An instance of ApiClient used to make HTTP requests.

Methods

getLanguages()

Fetches a collection of languages supported in the YouVersion Platform.
async getLanguages(options?: GetLanguagesOptions): Promise<Collection<Language>>
options
GetLanguagesOptions
Optional query parameters for pagination and filtering.
Returns
Promise<Collection<Language>>
A collection of Language objects.

Examples

// Get all languages
const languages = await languagesClient.getLanguages();

console.log(`Found ${languages.data.length} languages`);

languages.data.forEach(lang => {
  console.log(`${lang.id}: ${lang.display_names?.en || lang.language}`);
});

getLanguage()

Fetches details about a specific language in the Platform.
async getLanguage(languageId: string): Promise<Language>
languageId
string
required
The BCP 47 language code, optionally including script.Examples:
  • "en" - English
  • "es" - Spanish
  • "sr-Latn" - Serbian (Latin script)
  • "sr-Cyrl" - Serbian (Cyrillic script)
Must match BCP 47 format: language or language-Script
Returns
Promise<Language>
The requested Language object with full metadata.

Examples

// Get English language details
const english = await languagesClient.getLanguage('en');

console.log(english.id); // "en"
console.log(english.display_names?.en); // "English"
console.log(english.text_direction); // "ltr"
console.log(english.countries); // ["US", "GB", "CA", ...]
console.log(english.default_bible_id); // Default English Bible version ID

Complete Example

import { ApiClient, LanguagesClient, BibleClient } from '@youversion/platform-core';

// Initialize clients
const apiClient = new ApiClient({
  appKey: process.env.YOUVERSION_APP_KEY!,
});
const languagesClient = new LanguagesClient(apiClient);
const bibleClient = new BibleClient(apiClient);

// Get all languages with their display names
const languages = await languagesClient.getLanguages({
  page_size: '*',
  fields: ['id', 'display_names', 'default_bible_id', 'text_direction']
});

console.log(`Total languages: ${languages.data.length}`);

// Group by text direction
const ltrLanguages = languages.data.filter(l => l.text_direction === 'ltr');
const rtlLanguages = languages.data.filter(l => l.text_direction === 'rtl');

console.log(`LTR languages: ${ltrLanguages.length}`);
console.log(`RTL languages: ${rtlLanguages.length}`);

// Get languages with default Bibles
const withDefaultBible = languages.data.filter(l => l.default_bible_id);

console.log(`\nLanguages with default Bibles: ${withDefaultBible.length}`);

for (const lang of withDefaultBible.slice(0, 5)) {
  const displayName = lang.display_names?.en || lang.id;
  
  if (lang.default_bible_id) {
    const bible = await bibleClient.getVersion(lang.default_bible_id);
    console.log(`${displayName}: ${bible.title} (${bible.abbreviation})`);
  }
}

// Get detailed info for a specific language
const korean = await languagesClient.getLanguage('ko');

console.log(`\nKorean Language Details:`);
console.log(`  ID: ${korean.id}`);
console.log(`  Display Names:`, korean.display_names);
console.log(`  Text Direction: ${korean.text_direction}`);
console.log(`  Countries: ${korean.countries?.join(', ')}`);
console.log(`  Speaking Population: ${korean.speaking_population?.toLocaleString()}`);
console.log(`  Writing Population: ${korean.writing_population?.toLocaleString()}`);

if (korean.default_bible_id) {
  const defaultBible = await bibleClient.getVersion(korean.default_bible_id);
  console.log(`  Default Bible: ${defaultBible.title}`);
}

Best Practices

Language metadata rarely changes, so cache it to reduce API calls:
let languagesCache: Collection<Language> | null = null;

async function getLanguagesCached() {
  if (!languagesCache) {
    languagesCache = await languagesClient.getLanguages({
      page_size: '*',
      fields: ['id', 'display_names', 'text_direction']
    });
  }
  return languagesCache;
}

// Use cached data
const languages = await getLanguagesCached();
Display language names in the user’s preferred language:
const languages = await languagesClient.getLanguages();
const userLocale = 'es'; // User's preferred language

languages.data.forEach(lang => {
  const displayName = lang.display_names?.[userLocale] 
    || lang.display_names?.en 
    || lang.id;
  
  console.log(displayName);
});
Some languages have multiple scripts (e.g., Serbian, Azerbaijani):
const language = await languagesClient.getLanguage('sr');

if (language.scripts && language.scripts.length > 1) {
  console.log(`${language.id} has multiple scripts:`);
  
  for (const script of language.scripts) {
    const langWithScript = `${language.language}-${script}`;
    try {
      const variant = await languagesClient.getLanguage(langWithScript);
      console.log(`  ${script}: ${variant.script_name}`);
    } catch (error) {
      // Script variant might not be available
    }
  }
}
When you don’t need all language metadata, specify only required fields:
// Only need language IDs and display names for a dropdown
const languages = await languagesClient.getLanguages({
  page_size: '*',
  fields: ['id', 'display_names']
});

// Much faster and uses less bandwidth
Show only languages relevant to the user’s region:
// Detect user's country (from IP, browser, or user preference)
const userCountry = 'US';

// Get languages for that country
const regionalLanguages = await languagesClient.getLanguages({
  country: userCountry
});

console.log(`Languages in ${userCountry}:`);
regionalLanguages.data.forEach(lang => {
  console.log(`  - ${lang.display_names?.en}`);
});
Use language data to create an internationalized language picker:
async function buildLanguageSelector(userLocale: string = 'en') {
  const languages = await languagesClient.getLanguages({
    page_size: '*',
    fields: ['id', 'display_names', 'default_bible_id']
  });
  
  // Filter to languages with Bibles
  const withBibles = languages.data.filter(l => l.default_bible_id);
  
  // Sort by display name in user's locale
  return withBibles
    .map(lang => ({
      id: lang.id,
      name: lang.display_names?.[userLocale] 
        || lang.display_names?.en 
        || lang.id,
      bibleId: lang.default_bible_id
    }))
    .sort((a, b) => a.name.localeCompare(b.name));
}

// Use in UI
const options = await buildLanguageSelector('es');
// Render dropdown with options

Validation

The client validates all inputs using Zod schemas:
  • Language ID: Must match BCP 47 format (language or language-script)
  • Country Code: Must be 2-character ISO 3166-1 alpha-2 code (auto-converted to uppercase)
  • page_size: Must be a positive integer or "*"
  • fields: When page_size is "*", must specify 1-3 fields
try {
  // ✅ Valid
  await languagesClient.getLanguage('en');
  await languagesClient.getLanguage('sr-Latn');
  
  // ❌ Invalid - throws error
  await languagesClient.getLanguage('invalid');
  await languagesClient.getLanguage('en-US'); // Region not supported, use 'en'
  
  // ✅ Valid country code
  await languagesClient.getLanguages({ country: 'us' }); // Auto-converted to 'US'
  
  // ❌ Invalid page_size="*" without proper fields
  await languagesClient.getLanguages({
    page_size: '*'
    // Error: requires 1-3 fields
  });
  
  // ✅ Valid with fields
  await languagesClient.getLanguages({
    page_size: '*',
    fields: ['id', 'display_names']
  });
} catch (error) {
  console.error(error.message);
}

Type Definitions

GetLanguagesOptions

languages.ts:9
export type GetLanguagesOptions = {
  page_size?: number | '*';
  fields?: (keyof Language)[];
  page_token?: string;
  country?: string; // ISO 3166-1 alpha-2 country code
};

Language

See the Language schema for the complete type definition.

Build docs developers (and LLMs) love