Find your real take-home pay in Malaysia after EPF, SOCSO, EIS, SKBBK and PCB, then plan your income tax and EPF retirement. Also zakat, faraid and loan tools. Free and private.
翻译准备中
金融TypeScript · CSSGitHub @cakasuma在线运营者未确认
试用过了吗? 点一下就好,无需登录。
尚未检测到更新。GitHub 发布版本后会显示在这里。
Online calculators: basic, scientific, and Faraid (Islamic inheritance). Built with React + TypeScript + Tailwind CSS.
翻译准备中
正在加载完整 README。
查看完整 README ↗ToolHub MY is a mobile-first utility tools web app built with Vite + React + wouter routing.
/en/currency-converter/usd-to-myr)npm install
cp .env.example .env
npm run dev
VITE_ADSENSE_CLIENT – your AdSense publisher ID (e.g. ca-pub-...)VITE_ADSENSE_SLOT_TOP – ad slot ID for the global top ad placementVITE_ADSENSE_SLOT_HOME – ad slot ID for the homepage ad placementThe sample values in .env.example are placeholders; replace them with the IDs from your AdSense account. For Vercel, set the three VITE_ADSENSE_* variables in Project Settings → Environment Variables for Production, Preview, and Development, then rebuild and redeploy. The client is compiled at build time, so changing runtime-only variables does not update an existing deployment.
AdSense network scripts/requests are only enabled in production builds (import.meta.env.PROD).
The About and Contact pages link to the existing site operator at amammustofa.com. No direct contact email is currently configured. When the operator has a public support address, set CONTACT_EMAIL in client/src/config/legal.ts; the contact pages and privacy/terms pages will then expose it as a mail link.
Pageviews and custom events both go to Vercel Web Analytics:
<Analytics /> component in client/src/App.tsx collects pageviews automatically once you enable Web Analytics in your Vercel project's Analytics tab.pageview, cta_view, cta_click, lead_submit_success, lead_submit_error, calculator_complete) are emitted from client/src/lib/analytics.ts via @vercel/analytics's track(). Each is tagged with calculator, intent, and source so you can filter the funnel by tool.No env vars needed — the package picks up your Vercel project automatically when deployed.
DATABASE_URL – Postgres connection string used by server/db.ts (drizzle + postgres-js).When set, leads from the LeadCaptureCard (Faraid, Wasiat, Zakat, Salary) and event pings are persisted to the leads and calculation_events tables. Run npx drizzle-kit push to apply the schema. If unset, the server falls back to in-memory storage so the app still runs locally — leads and events are lost on restart. The endpoints POST /api/leads and POST /api/events are rate-limited per IP (20 req/min).
Supabase is plain Postgres + a built-in table editor, so it works with the existing DATABASE_URL setup with no code changes.
Create a project at supabase.com (free tier is enough). Pick a region close to your Vercel one.
In the project dashboard go to Project Settings → Database → Connection string.
You'll see three tabs. Use them like this:
| Use case | Tab to copy | Port | Why |
|---|---|---|---|
Vercel runtime (DATABASE_URL) | Transaction pooler | 6543 | Serverless functions open many short-lived connections; the transaction pooler handles that safely. Our driver already runs with prepare: false, which is required here. |
Local migrations (drizzle-kit push) | Direct connection (or Session pooler if your network is IPv4-only) | 5432 | Migrations need session-level features that the transaction pooler doesn't allow. |
Replace [YOUR-PASSWORD] in the URL with the database password you set when creating the project.
Apply the schema once from your laptop:
DATABASE_URL="postgres://...:5432/postgres" npx drizzle-kit push
This creates the leads and calculation_events tables.
In Vercel: Project Settings → Environment Variables → add DATABASE_URL with the transaction pooler URL (port 6543). Set it for Production, Preview, and Development.
Redeploy. Submit a test lead from /faraid, /wasiat, /zakat, or /salary, then go to the Supabase Table Editor → leads to see it land.
Notes:
drizzle-kit push are owned by the postgres role, so RLS is irrelevant — only your server connects with that role; the client never talks to Supabase directly./admin/leads page, gate it with basic auth or a session check; do not expose the Supabase anon key from the client.The converter (/currency-converter, plus a prerendered landing page per pair such as /currency-converter/usd-to-myr in en/ms/id) reads ECB reference rates from the free Frankfurter API in the browser, with no API key. A dated snapshot in client/src/lib/currency.ts is the offline fallback and the source of the numbers in prerendered HTML. Refresh it before deploying:
npx tsx script/update-fx-rates.ts && npx tsx script/generate-sitemap.ts
Add or remove pairs in client/src/config/currencyPairs.ts; routes, copy, sitemap entries and OG images are generated from that list.
npm run build
npm run start
This repo is ready for Vercel deployment:
vercel.json sets npm run build and output to dist/publicsitemap.xml; add useful original content before submitting those URLs for indexing.npm run build.dist/public.npm install.VITE_ADSENSE_CLIENTVITE_ADSENSE_SLOT_TOPVITE_ADSENSE_SLOT_HOMEDATABASE_URL (Supabase transaction pooler URL — see "Setting up Supabase" above)When you are ready to connect a subdomain (for example tools.example.com):
CNAME record pointing the subdomain to cname.vercel-dns.com.If you are using Cloudflare proxy mode, ensure SSL/TLS mode is compatible (typically Full or Full Strict).