PrayerTimesSG Updates
February 5th, 2026 updates

Today’s work was not about adding new features, but about making the existing system behave properly.

I fixed an issue where prayertimes.sg (vanilla JavaScript) could not reliably pull data from api.prayertimes.sg due to browser CORS restrictions. The API itself was working fine — curl, PHP, and other server-side requests all succeeded — but browser-based JavaScript was being blocked.

A useful clue came from a small but important observation:

A good friend of mine, Kamil, was able to pull the exact same API data using PHP without any issues, while my JavaScript fetch kept failing. That contrast immediately pointed to the browser as the real constraint. Not the API logic itself.

After tracing it step by step, the root causes turned out to be:

  • The /today endpoint was issuing a redirect instead of returning JSON directly
  • HTTPS requests were not being fully respected behind Nginx
  • CORS headers were not consistently present at the edge (Nginx level)

These have now been resolved.

What changed

  • /api/v1/prayer-times/today now returns JSON directly (no redirects)
  • HTTPS is correctly forwarded to the Ruby app via X-Forwarded-Proto
  • CORS headers are handled explicitly at the Nginx layer
  • Vanilla JavaScript frontends can now fetch the API without workarounds or proxies

The lesson here is simple but important: an API that works via curl or PHP does not automatically work in the browser.

With this resolved, it’s time to move forward and build v1.0 of prayertimes.sg — a cleaner, fully static frontend that talks directly to a public, read-only API. Exactly how I intended from the start.