hugo-unirate

May 26, 2026 · View on GitHub

Hugo Module that renders live currency conversions and exchange rates inside your site at build time, backed by the UniRate API. 170+ fiat currencies and crypto, with a free tier covering live conversion and supported-currencies listing.

100 USD = {{< currency from="USD" to="EUR" amount="100" >}}
USD/EUR rate: {{< rate from="USD" to="EUR" >}}

renders to:

100 USD = 92.43 EUR
USD/EUR rate: 0.9243

Install

Requires Hugo 0.141.0+ (uses the try keyword) and Go installed (Hugo modules use Go's module resolver — no Go code is shipped).

In your site's hugo.toml (or config.toml):

[module]
  [[module.imports]]
    path = "github.com/UniRate-API/hugo-unirate"

[params]
  [params.unirate]
    apiKey = "YOUR_UNIRATE_API_KEY"

Then:

hugo mod get github.com/UniRate-API/hugo-unirate

Get a free API key at https://unirateapi.com.

Avoid committing your key

Set the key via env var instead — Hugo reads HUGO_PARAMS_UNIRATE_APIKEY into site.Params.unirate.apiKey automatically:

export HUGO_PARAMS_UNIRATE_APIKEY=your_key
hugo --minify

Shortcodes

currency — convert an amount

{{< currency from="USD" to="EUR" amount="100" >}}    → 92.43 EUR
{{< currency USD GBP 50 >}}                          → 39.50 GBP   (positional)
{{< currency from="USD" to="JPY" amount="1" format="¥%.0f" >}}  → ¥147
argrequireddefaultnotes
fromnoUSDsource currency code
toyestarget currency code
amountno1numeric amount to convert
formatno%.2f %sGo printf format; receives (value, code)

rate — fetch the raw exchange rate

{{< rate from="USD" to="EUR" >}}                     → 0.9243
{{< rate USD JPY format="%.2f" >}}                   → 147.32
argrequireddefaultnotes
fromnoUSDsource currency code
toyestarget currency code
formatno%.4fGo printf format; receives float

Partials (use from your own templates)

Call directly from layouts when you need the numeric value, not formatted text:

{{ $eur := partialCached "unirate/convert.html" (dict
    "from" "USD" "to" "EUR" "amount" .Params.priceUSD
) .Params.priceUSD }}
<p>Price in EUR: <strong>{{ printf "€%.2f" $eur }}</strong></p>

Available partials:

partialreturnscontext keys
unirate/convert.htmlfloatfrom, to, amount
unirate/rate.htmlfloatfrom, to
unirate/currencies.html[]string(none)

All three use resources.GetRemote, so Hugo's built-in HTTP cache dedupes identical requests within a build. Wrap calls in partialCached to dedupe across multiple invocations with the same arguments.

How rates are fetched

Each unique (endpoint, params) combination triggers one HTTPS call to https://api.unirateapi.com during hugo build. Responses go through Hugo's resources.GetRemote cache (default lifetime: until you run hugo --gc). Failed requests log a WARN and render the value as 0 so your build never breaks because of a transient network blip.

To force fresh rates on every build (e.g. in CI on a schedule), pass a cacheBust value into the partial:

{{ partial "unirate/_api.html" (dict
    "endpoint" "/api/convert"
    "params" (dict "from" "USD" "to" "EUR" "amount" "100")
    "cacheBust" now.Unix
) }}

Configuration reference

keydefaultnotes
params.unirate.apiKey(empty — required)get one at unirateapi.com
params.unirate.apiBaseUrlhttps://api.unirateapi.comoverride for self-hosted/mock

Both can be set via HUGO_PARAMS_UNIRATE_APIKEY / HUGO_PARAMS_UNIRATE_APIBASEURL.

Free vs Pro

endpoint used byfree tierPro tier
currency, rate, currencies partialyesyes
historical rates (not yet exposed)noyes

Pro endpoints (/api/historical/*, commodities) return HTTP 403 on the free tier and would render as 0 with a WARN. They aren't wired up here — open an issue if you want them.

If you need rates outside Hugo, there are first-party clients for Python, Node, Go, Rust, Ruby, PHP, Swift, Java, and .NET.

Other UniRate clients

UniRate ships official client libraries and framework integrations across the ecosystem. The repos below are all maintained under the UniRate-API org.

Get a free API key at unirateapi.com.

License

MIT — see LICENSE.