How We Built a Fast, Static Quran & Hadith Website (55,000+ Hadith) with Next.js on Cloudflare Pages
Our team at Edu Reminder builds the Al Quran (★4.6) and Hisnul Muslim (★4.9) Android apps. This year we brought them to the web as The Muslim - ilmhub.tech: the Quran with 44 translations and classical tafsir, 25 hadith books (55,225 hadith), Hisnul Muslim duas, 47 reciters and prayer times. Free, no ads, no accounts.
This post is about the engineering: how to serve a lot of religious text fast, cheaply, and in a way Google can actually index.
The constraints
- Fully static. A static export of Next.js deployed to Cloudflare Pages. No server to scale or pay for.
- Cloudflare's per-deployment file limit. Every pre-rendered URL costs roughly 8 files (HTML plus RSC prefetch segments). 114 surahs x 6,236 ayahs x 55,225 hadith as individual pages would blow straight through it.
- SEO matters. People search for things like "Surah Ya-Sin with Bangla translation" or "Sahih Bukhari online". Those pages must contain the real text in the HTML.
Decision 1: pre-render only canonical pages
We pre-render the pages that deserve to rank - 114 surahs, 45 dua categories, 47 reciters, and hadith books and chapters - and nothing else. That keeps the deployment around 1,900 files for the Quran side.
The 604 mushaf pages (/page/:n) and 30 juz (/juz/:n) share one shell each. public/_redirects rewrites them with status 200 and the reader fetches the content client-side. Those shells are noindex, so Google sees exactly one URL per piece of content.
Decision 2: the main text is in the static HTML
The verse, translation and hadith JSON lives on Cloudflare R2 (assets.ilmhub.tech) so it costs nothing in egress and never bloats the deployment. But that CDN deliberately blocks crawlers, so anything fetched in the browser is invisible to Google.
The fix: render the main text at build time from the local data/ folder and pass it to the client reader as an initial prop. The browser only fetches extras (other translations, tafsir, audio timings). Search engines get the full surah or hadith chapter in the HTML, users get an instant page.
Decision 3: index books and chapters, not single hadith
55,225 hadith pages would cost ~440,000 files. Instead, each book and chapter is a pre-rendered, indexed page (e.g. Sahih Bukhari), and a single hadith is served from a shared shell plus the CDN. Same for duas: 45 categories are indexed, not each dua.
Decision 4: an app shell that never remounts
The header, section nav and mobile tab bar are rendered once by the root layout. Switching from Quran to Audio to Prayer Times is a client-side swap with no reload - and the audio player keeps playing while you browse. 47 reciters, verse-by-verse highlighting, a queue and repeat for memorisation.
Decision 5: SEO rules written down and tested
Every indexable page must have: generateStaticParams, a unique title and description, a canonical URL, exactly one <h1>, breadcrumb JSON-LD, Open Graph through one helper (so the share image is never dropped), and an entry in sitemap.ts.
Aliases like /quran/2 are 301 redirects, never duplicate pages. A Playwright suite checks all of it against the production build in Chromium, Firefox, WebKit, a Pixel 7 and an iPhone 14 - including RTL Urdu and what the HTML looks like to a search engine.
Results
- ~940 URLs in the sitemap, all discovered by Google on the first read.
- No servers, no database, near-zero hosting cost.
- Pages render instantly because the content is already in the HTML.
Try it
- Quran: Surah Ya-Sin, Surah Al-Kahf, Surah Al-Mulk
- Hadith: Hadith library
- Duas: Morning & evening adhkar
- Prayer times and Qibla
It's built as sadaqah jariyah - free, no ads, no sign-up. Feedback on performance or SEO is very welcome in the comments!
Comments
No comments yet. Start the discussion.