Hello, World! Trash Service Quote

Trash Service Instant Quote

Pick your service options to see an estimated price. (You can customize the pricing rules in the code.)

Fast estimate • No signup

Get a quote

Want this to email you the quote automatically? See the optional backend section below.
This gives you a clean quote form + a pricing engine you can tweak in the PRICING object. 2) Optional: Email the quote to you (simple backend) Static websites can’t email by themselves. Easiest: Cloudflare Workers (free tier) or Vercel. Here’s a Cloudflare Worker example. A) Worker code (worker.js) js Copy code export default { async fetch(request, env) { if (request.method === "OPTIONS") { return new Response(null, { headers: corsHeaders(request), }); } if (request.method !== "POST") { return new Response("Use POST", { status: 405, headers: corsHeaders(request) }); } const data = await request.json(); // Basic validation if (!data?.name || !data?.phone || !data?.email || !data?.quoteTotal) { return new Response(JSON.stringify({ ok: false, error: "Missing fields" }), { status: 400, headers: { "content-type": "application/json", ...corsHeaders(request) }, }); } // Send using MailChannels (works on Cloudflare Workers without extra setup) // Docs: https://github.com/mailchannels/mailchannels const msg = { personalizations: [{ to: [{ email: env.TO_EMAIL }] }], from: { email: env.FROM_EMAIL, name: "Trash Quote Bot" }, subject: `New Trash Service Quote Request: ${data.name}`, content: [ { type: "text/plain", value: `New quote request Name: ${data.name} Phone: ${data.phone} Email: ${data.email} ZIP: ${data.zip || ""} Details: Customer Type: ${data.customerType} Frequency: ${data.pickupFrequency} Bin Size: ${data.binSize} Bins: ${data.binsCount} Area: ${data.serviceArea} Extra Pickup: ${data.extraPickup} Estimated Total: $${data.quoteTotal} ` } ] }; const r = await fetch("https://api.mailchannels.net/tx/v1/send", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(msg), }); const ok = r.ok; return new Response(JSON.stringify({ ok }), { status: ok ? 200 : 500, headers: { "content-type": "application/json", ...corsHeaders(request) }, }); }, }; function corsHeaders(request) { const origin = request.headers.get("Origin") || "*"; return { "Access-Control-Allow-Origin": origin, "Access-Control-Allow-Methods": "POST, OPTIONS", "Access-Control-Allow-Headers": "Content-Type", }; } B) Add environment variables in Cloudflare TO_EMAIL = where you want the quote requests sent FROM_EMAIL = a sender address you control (some setups use a domain email) C) Front-end: send the quote to the Worker Add this button + code inside the HTML script (I’ll keep it short). After renderQuote(q) runs, you can POST: js Copy code async function sendQuote(q) { const payload = { name: $("name").value.trim(), phone: $("phone").value.trim(), email: $("email").value.trim(), zip: $("zip").value.trim(), customerType: q.inputs.customerType, serviceArea: q.inputs.serviceArea, pickupFrequency: q.inputs.pickupFrequency, binSize: q.inputs.binSize, binsCount: q.inputs.binsCount, extraPickup: q.inputs.extraPickup, quoteTotal: q.breakdown.total }; const res = await fetch("https://YOUR-WORKER-URL.workers.dev", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(payload) }); const out = await res.json(); if (out.ok) showMsg("Sent! We’ll contact you shortly.", true); else showMsg("Couldn’t send right now. Please call/text us."); } (You’d call sendQuote(q) after calculating the quote.) What I need from you to tailor the quote engine If you reply with: your prices (weekly/biweekly/monthly), whether you charge by bin size and how much, any service area upcharge or ZIP restrictions, commercial pricing rules (flat rate vs multiplier), …I’ll plug your real numbers in and also add “Call/Text” buttons + your branding (Pit Road Network style if you want). ChatGPT can make mistakes. Check important info.