Streamline processes
Most of the work of running a shop is repetitive, and repetition is where mistakes come from. These are internal tools: nobody sees them but me.
One file, one button
The whole gallery is described by one data file. Pages, sitemap and product feeds are generated from it, so there is one place to change a price or mark a piece as sold.
A local admin panel edits that file. It checks every change before saving and refuses what would break a page: a title too long for the product page, a description Google would cut off. It does not allow deleting a piece, because its links are already shared, and it keeps the last 40 versions of each file.
Publishing is one button that runs, in order: the tests, a dry-run deploy, the real deploy, an IndexNow ping to search engines, and a comparison of the live site against the local copy. That last step exists because “the deploy finished” and “the site shows what I have here” are different statements, and only the second one matters.
One file, two readers
The catalogue is loaded by the browser as a script, and it is also read by the Worker that renders the pages. The second reader has a constraint: Workers forbid eval, so the Worker cannot execute the file. It cuts out the object between the first { and the last } and parses it as JSON.
const text = await (await env.ASSETS.fetch(url)).text();
return JSON.parse(text.slice(text.indexOf("{"), text.lastIndexOf("}") + 1));
It is a few lines instead of a database, and it has a price. The object must be strict JSON, because a perfectly valid JavaScript object with unquoted keys loads in the browser and crashes every server-rendered page. And the comment at the top of the file must not contain a brace: one did, once, and the slice started inside the comment.
I still prefer it. The failure is loud and immediate, and a script checks that the file still parses before anything is published.
It worked in curl and returned 404 in the browser
This one cost me more than once. A new page answered 200 with the right HTML when I tested it from the terminal. In a real browser, the same address returned 404.
The cause: when a request looks like a page navigation, the platform’s static file server may answer it without ever calling the Worker, unless that route is listed to run the Worker first. A browser sends the header that marks a navigation. curl does not. So curl reached my code and the browser did not.
The fix is one line of configuration. The lesson is the rule that came with it: a new route is checked in a real browser, never with curl alone. A test that takes a different path from the user proves nothing about the user.
Listings without retyping
Two tools handle marketplace listings.
The first uploads them in bulk. Instead of copying an existing listing by hand and changing four things, I write those four things in a CSV: title, tags, photos and two lines of description. Everything else (category, sizes, prices, shipping, return policy) is cloned from a listing that is already set up correctly. Cloning is the design decision: the tool does not need to understand every setting the marketplace has, only to copy a set that is known to work.
The second turns the image of a design into a complete listing with a language model, and checks the result in code before I see it. How that checking works.
- JavaScript56.6%
- Python33.2%
- HTML4.7%
- TypeScript3.5%
- Shell1.1%
- Other0.9%