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 fromAccept-Language, persisted to a cookie. - 🛠️
useUniRateClient()server util — a direct, typed client for yourserver/routes. - 💱
<Currency>+<Rate>components — locale-awareIntlformatting. - 📦 Zero runtime dependencies.
@nuxt/kitis a peer (it ships with Nuxt). Nuxt 3 and Nuxt 4.
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_hereA 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.
<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:
| Method | Returns |
|---|---|
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) |
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') }
})<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><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 -->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, …).
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.
- Zero runtime dependencies;
@nuxt/kitis 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.
Official UniRate clients & framework integrations: Python · Node · React · Next.js · SvelteKit · NestJS · Astro · Eleventy · MCP server
MIT © UniRate API