A bookshop where a second-hand paperback, a brand-new hardback and an instant PDF download sit in the same catalogue, the same search and the same basket. That sounds unremarkable until you try to model it — and it is the reason this was built rather than bought.
- Catalogue
- 5,475 titles
- Built with
- Next.js 15 · Payload CMS 3 · PostgreSQL
- Runs on
- Vercel · Neon · Cloudflare R2
- Status
- Live · payments in progress
Three kinds of book, one shop.
Most shop platforms assume every product is the same shape. Books are not, and the differences are exactly the things a buyer cares about.
A used book has a condition
“Good” and “Like new” are the difference between a sale and a return. That has to be a first-class field with a grade, not a note in the description.
A PDF has no stock
It cannot sell out, it does not ship, and it must not be downloadable until it is paid for. Modelling it as a product with an inventory count of one is how digital shops leak files.
A new book has neither
No grade, no file — just stock and a price. Forcing all three through one product type means every page carries fields that do not apply to it.
They share one basket
Mixed baskets have to price delivery on the physical items only, and the free-delivery threshold has to know the difference. That logic lives in one place rather than three.
The shop as it runs.
Every figure below is real: the title count, the genre counts, the reading-age bands. They come from the live catalogue.
Brand-new releases, second-hand bargains and instant PDF downloads — one shop, one basket.
Browse all booksShop usedOne shop, three conditions
New, second-hand and PDF sit in the same catalogue and the same basket — which sounds obvious until you try to model it. A used copy needs a condition grade, a PDF needs a file and no stock count, and a new book needs neither. The delivery-threshold bar is live, not decorative: it reads the basket and tells you what is left to spend.
5,475 titles, four ways to narrow them
Condition, format, genre and reading age — the last one carrying real counts per key stage, because a parent shopping for a seven-year-old is a different search from a parent shopping for a subject. Every facet is a real query against the catalogue, not a client-side filter over a page of results.
A shop somebody runs, not a database with a skin
Deal of the Day, a bargain bin, featured picks and the series readers ask for by name — all editable in the admin without a developer. That was the whole point of embedding a CMS rather than hard-coding a storefront: the person who knows the stock can merchandise it on a Tuesday afternoon.
These are drawn reconstructions of the running storefront rather than screenshots — faithful to the live design, but redrawn. No customer, order or account data appears here or anywhere on this site.
The decisions worth defending.
Each of these was written down with its alternatives at the time, which is why they can be explained now rather than reconstructed.
What is finished, and what is not.
This is a build in progress, and describing it as a finished shop would be the same kind of overstatement this studio removes from its own pages.
Working, verified in production
- Catalogue of 5,475 titles, browsable and searchable
- Faceted browsing by condition, format, genre and reading age
- Author, publisher, genre and individual book pages
- Customer accounts — registration and sign-in
- Basket, including mixed physical and digital
- Checkout mechanics: orders with line items, VAT, shipping and status history
- Order confirmation and order history
- Content management: pages, posts, media, menus, site settings
- Sitemap, robots, structured data and per-page meta
Not done yet
- Payment gateway. Orders reach pending-payment and stop there. Nothing is charged.
- Signed PDF downloads gated on a paid order — built with the gateway, not before it.
- Bulk catalogue import from the supplier's spreadsheet.
- Incremental regeneration. Pages render dynamically today; caching is a deliberate later pass.
- Its own domain. Running on a deployment URL until one is attached.
Common questions.
Why not just build it on Shopify?
Because the data model does not fit. A used book needs a condition grade, a PDF needs a file and no stock count, and a new book needs neither — and all three have to sit in one basket with one delivery calculation. Shopify can be bent into that shape with variants and apps, but the bending is permanent and you never own the model. It stayed on the table as a fallback if the custom build had slipped.
Why not WordPress and WooCommerce?
It was considered and rejected in writing. It means a second stack in a second language to secure and update, and the catalogue logic ends up spread across plugins nobody owns. Payload gives the same WordPress-like editing experience — pages, posts, media, drafts, versions — inside the same Next.js application, so there is one deploy and one thing to patch.
Is it actually live?
Yes. It runs on Vercel with a Neon Postgres database and Cloudflare R2 for media, deploying automatically from the main branch. Customer accounts, the basket and checkout mechanics were each verified against production rather than assumed from a local run.
Can you buy a book on it today?
Not yet, and the site does not pretend otherwise. Orders are created and land in a pending-payment state with line items, VAT and shipping calculated — everything up to the moment money moves. The payment gateway is the next piece of work; until it is connected, nothing is charged.
What happens to the PDFs?
They are held as protected files against the book record rather than sitting on a public URL. Signed, expiring download links gated on a paid order are built alongside the payment gateway, for the obvious reason that there is no point issuing entitlements before there is a payment to attach them to.
Could you build something like this for us?
Yes, and the honest first question is whether you should. If your catalogue fits a standard product model, Shopify will be faster and cheaper and we will say so. Custom earns its keep when the model is genuinely unusual — mixed conditions, digital entitlements, unusual fulfilment — or when owning the data outright matters. We scope that before quoting.
Got a catalogue that does not fit a template?
Mixed conditions, digital entitlements, unusual fulfilment — the cases where an off-the-shelf shop fights you. We will tell you honestly if a standard platform would do the job cheaper.
- 01Your catalogue — how many products, and how far they differ
- 02Where a template breaks — the specific fields that do not fit
- 03Build or buy — including when buying is the right answer
- 04A fixed price — in writing, within 24 hours of the call