Guide · 4 min read · Updated 2026-05-08
How to display the Saudi Riyal symbol (U+20C1) in Vue 3
First-class Vue 3 components for the official SAMA Saudi Riyal sign. Install once, render with <RiyalPrice>, edit with <RiyalInput v-model mask>, and read live SAR exchange rates with the useRiyalRate composable. SSR-safe, Nuxt-ready.
If you’re building a Saudi e-commerce or fintech app on Vue 3 (or Nuxt), the riyal/vue entry gives you idiomatic components for the official Saudi Riyal symbol — no Web-Component wrapper required.
Install
pnpm add riyal vue
# or npm install riyal vue
vue ≥ 3.4 is an optional peer dependency. The components are render-function based (defineComponent + h()), so no Vue compiler plugin is needed in your app.
Basic usage
<script setup lang="ts">
import { ref } from "vue";
import {
RiyalSymbol, RiyalIcon, RiyalPrice,
AnimatedRiyalPrice, RiyalInput, useRiyalRate,
} from "riyal/vue";
const amount = ref<number | "">(2499.99);
const usd = useRiyalRate("USD");
</script>
<template>
<RiyalSymbol :size="24" />
<RiyalIcon :width="32" :height="32" />
<RiyalPrice :amount="2499.99" locale="ar-SA" />
<AnimatedRiyalPrice :amount="amount" :duration-ms="600" />
<RiyalInput v-model="amount" mask />
<span v-if="usd.rate.value">
{{ (Number(amount) * usd.rate.value).toFixed(2) }} USD
</span>
</template>
Masked input — paste anything
Pass mask to <RiyalInput> and the input becomes a format-as-you-type field that handles paste of every common SAR string format:
"SAR 2,499.99"→2499.99" 2,499.99"→2499.99"٢٤٩٩٫٩٩"→2499.99(Arabic-Indic digits)"99.90 ر.س"→99.9
It also strips RTL marks, normalises Arabic decimal/grouping characters, enforces a max-decimals window, and preserves caret position via a digit-counting algorithm — so cursor placement during edits stays where the user expects.
SSR & Nuxt
Every component is SSR-safe. RiyalPrice and RiyalSymbol render the same markup on the server and client, so they don’t cause hydration mismatches inside <ClientOnly> blocks. The useRiyalRate composable defers the fetch to onMounted, so it stays server-render-safe.
Cart, VAT, conversion
import { lineItem, cartTotal } from "riyal/cart";
const items = [
lineItem({ unit: 75, qty: 1 }),
lineItem({ unit: 45, qty: 2 }),
];
const totals = cartTotal(items, { shipping: 20, discount: 10 });
// → { subtotal, vat, shipping, total, ... }
The cart helpers default to Saudi 15% VAT and apply discounts proportionally to net + VAT, matching how Saudi receipts present them.
Next steps
- Live demo: https://riyal.js.org
- API reference: https://riyal.js.org/#reference
- npm: npmjs.com/package/riyal
Built by Pooya Golchian · riyal on npm · live demo