Skip to content

Browser Usage

WARNING

This library does not work in the browser. The Chabad.org API does not set CORS headers, so browsers will block requests made directly from client-side code.

Why It Doesn't Work

When you call fetch() from a browser to a different origin (like chabad.org), the browser sends a preflight CORS request. The Chabad.org API does not respond with the required Access-Control-Allow-Origin header, so the browser blocks the response.

This is a browser security restriction — it cannot be bypassed from client-side JavaScript.

Workarounds

1. Proxy Through Your Own Server

Call this library from your backend and expose the data through your own API:

ts
// app/api/zmanim/route.ts
import { getZmanimByZip } from "chabad-org-zmanim";

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const zip = Number(searchParams.get("zip") || "11213");

  const result = await getZmanimByZip(zip, new Date());
  return Response.json(result);
}
ts
// server.ts
import express from "express";
import { getZmanimByZip } from "chabad-org-zmanim";

const app = express();

app.get("/api/zmanim", async (req, res) => {
  const zip = Number(req.query.zip) || 11213;
  const result = await getZmanimByZip(zip, new Date());
  res.json(result);
});

app.listen(3000);
ts
// src/index.ts
import { Hono } from "hono";
import { getZmanimByZip } from "chabad-org-zmanim";

const app = new Hono();

app.get("/api/zmanim", async (c) => {
  const zip = Number(c.req.query("zip") || "11213");
  const result = await getZmanimByZip(zip, new Date());
  return c.json(result);
});

export default app;

2. Serverless Functions

Use a serverless function as a lightweight proxy:

ts
import { getZmanimByZip } from "chabad-org-zmanim";

export default {
  async fetch(request: Request): Promise<Response> {
    const url = new URL(request.url);
    const zip = Number(url.searchParams.get("zip") || "11213");

    const result = await getZmanimByZip(zip, new Date());

    return new Response(JSON.stringify(result), {
      headers: {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*",
      },
    });
  },
};
ts
// api/zmanim.ts
import { getZmanimByZip } from "chabad-org-zmanim";

export const config = { runtime: "edge" };

export default async function handler(request: Request) {
  const { searchParams } = new URL(request.url);
  const zip = Number(searchParams.get("zip") || "11213");

  const result = await getZmanimByZip(zip, new Date());
  return Response.json(result);
}

3. Build-Time / Static Generation

If you don't need real-time data, fetch zmanim at build time:

ts
// In a static site generator or build script
import { getZmanimRange } from "chabad-org-zmanim";
import { writeFileSync } from "fs";

const result = await getZmanimRange(
  11213, 2,
  new Date("2025-03-01"),
  new Date("2025-03-31"),
);

writeFileSync("public/zmanim-march.json", JSON.stringify(result));

Then load the JSON file from your client-side code.

Unofficial client. Not affiliated with or endorsed by Chabad.org.