Skip to main content

Overview

The currency module provides utilities for formatting monetary values and fetching Venezuelan exchange rates from the BCV (Banco Central de Venezuela). Module: lib/currency.ts

formatCurrency

Formats a numeric value as currency using the Intl.NumberFormat API with caching for performance.

Function Signature

function formatCurrency(
  value: number,
  currency: string,
  locale?: string
): string

Parameters

value
number
required
The numeric value to format
currency
string
required
The ISO 4217 currency code (e.g., “USD”, “VES”)
locale
string
default:"es-VE"
The locale string for formatting. Defaults to Venezuelan Spanish

Returns

formatted
string
The formatted currency string, or ”—” if the value is not finite

Examples

import { formatCurrency } from "@/lib/currency"

const amount = 1234.56
const formatted = formatCurrency(amount, "USD")
// Result: "$1,234.56"

const vesAmount = formatCurrency(45000, "VES")
// Result: "Bs. 45.000,00"
The function uses an internal cache (formatterCache) to avoid recreating Intl.NumberFormat instances, improving performance when formatting multiple values with the same currency/locale combination.

formatUsd

Convenience function for formatting USD currency values.

Function Signature

function formatUsd(value: number): string

Parameters

value
number
required
The numeric value to format as USD

Returns

formatted
string
The formatted USD string

Example

import { formatUsd } from "@/lib/currency"

const balance = formatUsd(2500.75)
// Result: "$2,500.75"

formatVes

Convenience function for formatting VES (Venezuelan Bolivar) currency values.

Function Signature

function formatVes(value: number): string

Parameters

value
number
required
The numeric value to format as VES

Returns

formatted
string
The formatted VES string

Example

import { formatVes } from "@/lib/currency"

const balance = formatVes(150000)
// Result: "Bs. 150.000,00"

fetchBcvRate

Fetches the current official USD to VES exchange rate from the BCV via the DolarAPI.

Function Signature

async function fetchBcvRate(signal?: AbortSignal): Promise<ExchangeRate | null>

Parameters

signal
AbortSignal
Optional AbortSignal for cancelling the request

Returns

result
ExchangeRate | null
An object containing the exchange rate information, or null if the request fails
currency
string
The currency code (always “VES”)
rate
number
The exchange rate (VES per 1 USD)

Example

import { fetchBcvRate } from "@/lib/currency"

const controller = new AbortController()
const rate = await fetchBcvRate(controller.signal)

if (rate) {
  console.log(`1 USD = ${rate.rate} ${rate.currency}`)
  // Example: "1 USD = 36.50 VES"
} else {
  console.error("Failed to fetch BCV rate")
}
The function makes a request to https://ve.dolarapi.com/v1/dolares/oficial with cache: "no-store" to ensure fresh data.

useBcvRate

React hook for managing BCV exchange rate data with automatic loading, error handling, and optional refresh intervals.

Hook Signature

function useBcvRate(options?: UseBcvRateOptions): UseBcvRateResult

Parameters

options
UseBcvRateOptions
Configuration options for the hook
refreshInterval
number
Optional interval in milliseconds for automatically refreshing the rate

Returns

result
UseBcvRateResult
An object containing the rate state and control functions
rate
number | null
The current exchange rate, or null if not yet loaded or on error
loading
boolean
true while the rate is being fetched
error
string | null
Error message if the fetch failed, otherwise null
refresh
() => void
Function to manually trigger a rate refresh

Examples

import { useBcvRate } from "@/lib/currency"

function ExchangeRateDisplay() {
  const { rate, loading, error } = useBcvRate()

  if (loading) return <p>Loading exchange rate...</p>
  if (error) return <p>Error: {error}</p>
  if (!rate) return <p>No rate available</p>

  return <p>1 USD = {rate} VES</p>
}
The hook automatically cleans up on unmount and handles abort scenarios properly. It also respects component mounting state to avoid setting state on unmounted components.

Types

ExchangeRate

type ExchangeRate = {
  currency: string
  rate: number
}
Represents an exchange rate response from the BCV API.

UseBcvRateOptions

type UseBcvRateOptions = {
  refreshInterval?: number
}
Configuration options for the useBcvRate hook.

UseBcvRateResult

type UseBcvRateResult = {
  rate: number | null
  loading: boolean
  error: string | null
  refresh: () => void
}
Return value from the useBcvRate hook.

Performance Considerations

  • Formatter Caching: The formatCurrency function caches Intl.NumberFormat instances by locale and currency combination, avoiding repeated instantiation overhead.
  • Request Deduplication: When using useBcvRate, the hook manages a single request at a time and prevents race conditions with mount state tracking.
  • No-Store Cache: The fetchBcvRate function uses cache: "no-store" to ensure fresh exchange rate data on every request.

Error Handling

All currency functions handle edge cases gracefully:
  • formatCurrency returns ”—” for non-finite values (NaN, Infinity)
  • fetchBcvRate returns null on network errors or invalid responses
  • useBcvRate exposes error state with user-friendly messages in Spanish

Build docs developers (and LLMs) love