Skip to content

UniRate-API/nuxt-unirate

Repository files navigation

@unirate/nuxt

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:

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)

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

License

MIT © UniRate API

About

Nuxt module for the UniRate currency-exchange API — server proxy (key stays server-side), useUniRate()/useCurrency() composables, <Currency>/<Rate> components. Zero runtime deps.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors