← cd ../
// notes

A print shop price calculator with a live delivery date, without a backend request

How the calculators on Denia Print show a price and a delivery date with a countdown, computed in the browser from data that is already on the page, and how the server checks every price again.

published
author
Nicky Mitnick

The problem

When you order print, two questions come first: what does it cost and when do I have it. On Denia Print I wanted both answered while you click through the options, on a static site, without a spinner after every choice.

The price is the easier half. The delivery date is harder. It depends on the production days of the exact combination you picked, the supplier’s daily order cutoff, public holidays in two countries and the time it is right now.

The approach

Price. The site is static Astro on Cloudflare Pages. For most products the calculator reads a price table that is built into the site. That table is rebuilt from the supplier’s API every week and deployed, so choosing a quantity or a paper type needs no request at all. Banners are priced per size, so they ask a small endpoint for a live price. The extended catalogue does the same, with the answer cached at the edge for 12 hours per variant.

Delivery date. The calculator shows a line like “Order before 11:30 (2 h 14 min left) and receive it Wed 7 Oct to Thu 8 Oct”. It is computed in the browser from four things:

  • the production days of the chosen combination, which already come with the price data
  • the supplier’s cutoff: 11:30 Amsterdam time, Monday to Friday
  • one working day for my own handling, because I check the file before it goes to the supplier
  • a list of public holidays: Dutch ones for production, Spanish national ones plus those of the Comunitat Valenciana for delivery in Dénia and the Marina Alta

The cutoff is calculated in the Amsterdam time zone, so daylight saving time is handled by the browser, and it is displayed in the visitor’s own time zone. The line redraws every 30 seconds, when the tab becomes visible again and when the pickup box in the order form changes. If you collect in Dénia, it reads “available from” the later date. Only the date is announced to screen readers when it changes, never the ticking countdown.

I calibrated the rule against the supplier’s own minimum delivery date for 40 combinations of product and speed. Order day plus the production days matched 21 times, was later 17 times and earlier twice. With my handling day on top, the range I show is on the late side in 39 of 40 cases. A few products run slower than their production days suggest, so those get extra working days from a small table.

The date goes along in the order lines and in the emails, so the customer and I look at the same promise.

Checking the price again. A price that the browser computed cannot be trusted by the server. The cart lives in localStorage with a maximum of 20 lines, and if storage is blocked the site still works per product. Before the cart is sent, the page asks the same sources as the calculators for the prices again. A changed price or a product that is no longer on sale is marked and blocks sending. It is never adjusted silently.

Then the server does it once more for every line: table products against the price table, banners and catalogue items against a live quote from the supplier. A line that does not match is flagged, and the dashboard holds back the supplier order for it until someone has looked. For the extended catalogue, the browser only knows option positions. The supplier’s article code stays on the server.

The trade-offs

  • The date is an estimate, and I say so with a range. I chose to err late: every counted day must be a working day in both countries. An order that arrives a day early is fine, the other way round is not.
  • The holiday list is maintained by hand, once a year. A test fails two months before the list runs out, so I cannot forget it. A missing year would only make dates around its holidays one day too optimistic.
  • The cutoff is hard-coded. If the supplier moves it, I have to move it too. The calibration needs repeating now and then.
  • The countdown uses the visitor’s clock. A wrong clock on the device gives a wrong countdown.
  • Live quotes are capped. At most 10 lines per checkout get a live supplier quote. The rest are flagged for a check by hand, so one cart cannot fan out into 20 supplier calls.

More about the shop is on the Denia Print project page.