@unirate/nuxt

July 8, 2026 ยท View on GitHub

ci npm

Nuxt module for the UniRate currency-exchange API.

  • ๐Ÿ”’ Server proxy โ€” your API key stays on the server; the browser only ever talks to your own app.
  • ๐Ÿงฉ useUniRate() composable โ€” universal (SSR + client) rate/convert/historical/VAT/time-series helpers.
  • ๐ŸŒ useCurrency() composable โ€” detect the visitor's currency from Accept-Language, persisted to a cookie.
  • ๐Ÿ› ๏ธ useUniRateClient() server util โ€” a direct, typed client for your server/ routes.
  • ๐Ÿ’ฑ <Currency> + <Rate> components โ€” locale-aware Intl formatting.
  • ๐Ÿ“ฆ Zero runtime dependencies. @nuxt/kit is a peer (it ships with Nuxt). Nuxt 3 and Nuxt 4.

Install

npm install @unirate/nuxt
// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@unirate/nuxt'],
  unirate: {
    // Prefer env: NUXT_UNIRATE_API_KEY (or UNIRATE_API_KEY). Avoid hardcoding.
    apiKey: process.env.NUXT_UNIRATE_API_KEY,
  },
})

Get a free API key at unirateapi.com. Set it via the NUXT_UNIRATE_API_KEY environment variable so it never ends up in source control:

# .env
NUXT_UNIRATE_API_KEY=your_key_here

Why a proxy?

A currency API key is a server secret. This module registers a server route (default /api/_unirate) that injects the key and forwards only an allow-listed set of UniRate paths. The useUniRate() composable calls that route โ€” so the key is never shipped in the client bundle, even during SSR hydration. Set addProxy: false if you only use the server util.

Usage

Composable (pages / components)

<script setup lang="ts">
const { getRate, convert, listCurrencies } = useUniRate()

// SSR-friendly: wrap in useAsyncData so it runs once and hydrates.
const { data: rate } = await useAsyncData('usd-eur', () => getRate('USD', 'EUR'))
const { data: total } = await useAsyncData('cart', () => convert('USD', 'EUR', 49.99))
</script>

<template>
  <p>1 USD = <Rate from="USD" to="EUR" :rate="rate ?? 0" /> EUR</p>
  <p>Total: <Currency :amount="total ?? 0" currency="EUR" /></p>
</template>

useUniRate() returns:

MethodReturns
getRate(from, to?)number (pair) or Record<string, number> (all rates from from)
convert(from, to, amount)number
listCurrencies()string[]
getHistoricalRate(date, from, to?, amount?)number or Record<string, number> (Pro)
getTimeSeries(start, end, base?, currencies?, amount?)Record<string, Record<string, number>> (Pro)
getVatRates(country?)all VAT rates or one country
getHistoricalLimits()available historical ranges (Pro)

Server util (server/ routes)

When you need the typed client directly on the server (key stays server-side):

// server/api/price.get.ts
export default defineEventHandler(async () => {
  const unirate = useUniRateClient()
  return { eur: await unirate.convert('EUR', 100, 'USD') }
})

Visitor currency

<script setup lang="ts">
const { currency, setCurrency } = useCurrency() // e.g. 'GBP' for an en-GB visitor
</script>

<template>
  <select :value="currency" @change="setCurrency(($event.target as HTMLSelectElement).value)">
    <option>USD</option><option>EUR</option><option>GBP</option>
  </select>
</template>

Components

<Currency :amount="1234.5" currency="EUR" :decimals="2" locale="de-DE" />
<!-- โ†’ 1.234,50 โ‚ฌ -->

<Rate from="USD" to="JPY" :rate="157.42" :decimals="2" />
<!-- โ†’ 157.42 -->

Configuration

unirate: {
  apiKey:       process.env.NUXT_UNIRATE_API_KEY, // or UNIRATE_API_KEY
  baseUrl:      'https://api.unirateapi.com',     // override for self-host/testing
  timeoutMs:    30000,
  addProxy:     true,                              // register the server proxy route
  proxyRoute:   '/api/_unirate',                   // where the proxy is mounted
  allowedPaths: undefined,                         // restrict the proxy's path allow-list
  components:   true,                              // register <Currency> + <Rate>
  prefix:       '',                                // e.g. 'Uni' โ†’ <UniCurrency>, <UniRate>
  cookieName:   'unirate_currency',                // used by useCurrency()
}

All values can also be supplied through Nuxt runtime config env overrides (NUXT_UNIRATE_API_KEY, NUXT_UNIRATE_BASE_URL, โ€ฆ).

Errors

Server-side calls (useUniRateClient()) throw typed errors: UniRateError and its subclasses AuthenticationError (401), ProRequiredError (403 โ€” historical/time-series are Pro-gated on the free tier), InvalidCurrencyError (404), InvalidRequestError (400), RateLimitError (429). Proxy requests surface the upstream status code to useUniRate() via $fetch.

Security

  • Zero runtime dependencies; @nuxt/kit is a peer provided by Nuxt itself.
  • The API key is read from server runtime config only โ€” never bundled client-side.
  • The proxy forwards an allow-listed set of paths, not arbitrary upstream URLs.
  • Published to npm with provenance attestation.

Part of the UniRate ecosystem

Official UniRate clients & framework integrations: Python ยท Node ยท React ยท Next.js ยท SvelteKit ยท NestJS ยท Astro ยท Eleventy ยท MCP server

UniRate ecosystem

UniRate ships official integrations for 40+ ecosystems, all maintained under the UniRate-API org.

Core clients (9 languages) Python ยท Node.js / TypeScript ยท Go ยท Rust ยท Java ยท Ruby ยท PHP ยท .NET ยท Swift

JavaScript / TypeScript React ยท Next.js ยท Remix ยท SvelteKit ยท Vue ยท Angular ยท Nuxt ยท NestJS ยท tRPC

Static-site generators Astro ยท Eleventy ยท Hugo ยท Jekyll

CMS & e-commerce Wagtail ยท WordPress ยท WooCommerce ยท Drupal ยท Strapi ยท Medusa ยท Symfony ยท Laravel ยท Directus

Data, AI & backend LangChain (Python) ยท LangChain.js ยท FastAPI ยท Flask ยท Django REST Framework ยท Apache Airflow ยท dbt

Platform & tools MCP server ยท CLI ยท Cloudflare Workers ยท Home Assistant ยท n8n ยท Google Sheets ยท VS Code ยท Obsidian

Money library bridges money gem (Ruby) ยท NodaMoney (.NET)

Get a free API key at unirateapi.com.

License

MIT ยฉ UniRate API