fonts quran.ws

Use Quran fonts in your app

Three recipes cover most apps: (1) Unicode text fonts — drop in @font-face and render ayat directly. (2) Page-glyph fonts — one font per page, paired with a PUA codepoint map. (3) Tajweed images — no font at all, just PNGs.

Recipe 1 · Unicode text font

Unicode text fonts render any ayah directly — no paired data required.

/* 1. Load the font */
@font-face {
    font-family: 'UthmanicHafs';
    src: url('https://fonts.quran.ws/assets/fonts/uthmanic-hafs-v22.woff2') format('woff2');
    font-display: swap;
}

/* 2. Use it on any Arabic text */
.quran {
    font-family: 'UthmanicHafs', 'Amiri', serif;
    direction: rtl;
    font-size: 2rem;
    line-height: 2.3;
}

Recipe 2 · Page-glyph font

Page-glyph fonts do not render Unicode. You must load the paired data file (mushaf.txt for v1/v1.5/v2, quran.json for v4) to know which PUA codepoints go on which page.
<!-- 1. Load the font for the specific page you want -->
<style>
    @font-face {
        font-family: 'QCF_P001';
        src: url('https://fonts.quran.ws/assets/fonts/qpc-hafs-v1/QCF_P001.woff2') format('woff2');
    }
    .page-glyph {
        font-family: 'QCF_P001';
        unicode-bidi: bidi-override; /* PUA defaults to LTR; override to RTL */
        direction: rtl;
        font-size: 2rem;
    }
</style>

<!-- 2. Fetch the paired ayah-keyed glyph data -->
<script>
const data = await fetch('https://fonts.quran.ws/bundles/qpc-hafs-v1/quran-glyphs.json').then(r => r.json());
// Each ayah is {surah, ayah, chunks: [{p, family, file, text}]} — render the first chunk
const ayah = data.ayat[0];
document.querySelector('.page-glyph').textContent = ayah.chunks.map(c => c.text).join('');
</script>

<!-- 3. Render -->
<div class="page-glyph"></div>

Recipe 3 · Tajweed images

Tajweed data carries rule tags per word. Pair with a tajweed-aware font (QPC V4) or render with coloured spans.

<!-- No font needed — pair the tajweed-coloured mushaf text with any renderer. -->
<!-- Grab the ready-to-use bundle from https://fonts.quran.ws/bundles/hafs-tajweed/ -->
<script>
const r = await fetch('https://fonts.quran.ws/bundles/hafs-tajweed/quran.json').then(r => r.json());
const ayah = r.ayat.find(a => a.surah === 2 && a.ayah === 255);
document.querySelector('.ayah').textContent = ayah.text;
</script>

<span class="ayah"></span>

Font ↔ data pairing

Version Font name Page → font Data file
v1 QCF_P{page:03d} QCF_P{page:03d} hafs-glyphs/v1/data/mushaf.txt
v1.5 page_{page} page_{page} hafs-glyphs/v1.5/data/mushaf.txt
v2 QCF2{page:03d} QCF2{page:03d} hafs-glyphs/v2/data/mushaf.txt
v4 Hafs QCF4_Hafs_{range:02d}_W per-word p field hafs-glyphs/v4/data/quran.json
v4 Warsh QCF4_Warsh_{range:02d}_W per-word p field warsh-glyphs/v4/data/quran.json