What Is a Digital Store? Three Shapes, and What 'Owned' Actually Costs
Marketplace listing, hosted platform, or owned storefront: the four real files (75 to 373 lines) this site's entitlement engine and download route are built from.
A digital store is a storefront that sells things a buyer receives instantly — a file, a license, an account entitlement — with no shipping and no physical inventory. That definition covers three very different implementations: a listing on someone else's marketplace, a shop built on a hosted commerce platform, and a storefront a business owns outright, code and all. This site is the third kind, and its own architecture is the concrete answer to what that actually requires.
The three shapes a digital store takes
| Shape | Example | What you get | What you own |
|---|---|---|---|
| Marketplace listing | Gumroad, Etsy's digital section | A product page, checkout, and file delivery on their domain (or a subdomain) | Nothing but the file itself — no SEO equity, no customer data beyond what the platform shares |
| Hosted platform store | Shopify, a page-builder's commerce plugin | Your own domain, a checkout you configure, a dashboard | The storefront's content, not its code — you're bound to what the platform's checkout and entitlement model support |
| Owned storefront | This site | Every layer — product pages, checkout integration, entitlement records, file delivery, buyer dashboard | All of it, which means all of it is also your bug to fix |
Almost every "what is a digital store" guide stops at the first row's mechanics — browse, buy, download — because that's what a shopper experiences regardless of which shape sits behind it. The interesting engineering is entirely in the third row, and it's the one no listicle inventories because none of them run one.
What "owned" actually means, file by file
This storefront sells 111 cataloged products across four categories — 9 admin dashboards, 66 landing pages, 35 shop templates, 1 ecommerce template — each a real license a buyer holds, not a one-off file transfer. Four systems make that work, and each is a real file in this repo:
The catalog (src/data/catalog.ts) is the product-and-pricing source of truth: every product's slug, status (available/coming-soon), pricing tier, and latestVersion. A product's slug is a stable ID — it's what an entitlement record references, which is why a slug is never reused once it's sold.
The entitlement engine (src/lib/entitlements.ts, 75 lines) is pure logic with no database or network calls in it at all — one function, slotCovers(), answering "does this buyer's slot cover this download target":
// src/lib/entitlements.ts
export function slotCovers(slot: Slot, target: DownloadTarget): boolean {
if (slot.status !== "active") return false;
switch (slot.kind) {
case "all_access":
return true;
case "all_templates":
return target.framework !== "backend";
case "template_single":
return (
slot.productSlug === target.productSlug &&
target.framework !== "backend"
);
}
}
Three purchase shapes — one template, every template, or every template plus the backend — collapse into one exhaustive switch with no fallthrough. That's the entire commerce logic a "digital store" boils down to underneath the checkout UI: a yes/no answer to "can this specific buyer have this specific file."
The download route (src/app/api/download/route.ts, 157 lines) re-runs that check on every request — never trusting a cached "you own this" flag from the page render, because a page render happened seconds or months ago and an entitlement can be revoked (a chargeback, a refund) in between. The actual files sit in a private Supabase storage bucket, not a public CDN URL, so a direct link with no valid session gets nothing.
The delivery layer (src/lib/download.ts, 373 lines) is the largest of the four, and it's the part every "start a digital store" guide skips entirely: rate limiting per buyer per hour, resolving which version a buyer's entitlement currently maps to (so a re-released v2.1 doesn't require re-issuing anything), and naming the downloaded file after the product rather than an opaque hash.
Where each shape's job actually lives
| Job | Marketplace listing | Hosted platform | Owned storefront (here) |
|---|---|---|---|
| Product page + SEO | Platform's, not yours | Yours, within the platform's templates | Fully yours — 111 pages, sitemap, JSON-LD, all generated from the catalog |
| Checkout | Platform's | Platform's, configurable | Integrated (LemonSqueezy as merchant of record) but the surrounding flow is yours |
| Entitlement record | Platform's database | Platform's database | Your own Postgres row, governed by your own RLS policy |
| File delivery | Platform's CDN | Platform's storage | Your own private bucket + your own authorization check on every request |
| What breaks and who fixes it | Their outage, their bug | Their outage; your configuration bugs | Every layer above is your bug |
That bottom-right cell is the real cost of "owned." It's also why the six-jobs breakdown in Gumroad alternative exists as its own post — this one answers "what is a digital store," that one answers "what does it cost to run your own."
When each shape is the right call
- Marketplace listing — you're testing whether a product sells at all, or the volume doesn't justify engineering time. Zero of the four systems above are yours to build.
- Hosted platform — you need your own domain and brand, and your entitlement logic is simple (one product, one price, no license tiers). The platform's checkout and delivery cover it.
- Owned storefront — you have enough products, or tiered licensing complex enough (single-template, all-templates, all-access, as here), that a platform's generic entitlement model stops fitting, and the SEO surface of 111+ product pages is worth owning outright.
The part every definition skips: who's the merchant of record
Every "what is a digital store" explainer describes the shopping experience and skips the one legal detail that decides how much of the store you actually have to build: who is the merchant of record for tax purposes. This storefront uses LemonSqueezy as its checkout provider specifically because it acts as merchant of record — it registers for VAT/sales tax in every jurisdiction it sells into and remits it, so this codebase's checkout integration contains zero tax-calculation logic of its own. A payment processor that is not merchant of record (Stripe used directly, for instance) leaves that obligation with the seller, which is a materially different amount of engineering and compliance work hiding behind what looks like the same "add to cart" button. LemonSqueezy vs. Stripe covers that split in more depth for anyone evaluating checkout providers specifically.
That distinction is also why the table above lists "checkout" as a single row across all three shapes — the visible integration work is similar regardless of shape, but the legal surface underneath it is not, and it's the one part of "what is a digital store" that a screenshot of a checkout page can never show you.
Mistakes and troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Buyer's download link 404s after a refund | The entitlement check is re-run per request (correct) and now denies it | Working as intended — a cached "you own this" state on the client would be the actual bug |
| A retired product's page still gets sold | Status wasn't flipped to coming-soon/unavailable in the catalog | Never delete a slug that's ever sold; flip its status instead and keep its zip in place |
| Buyer downloads the old version after a release | Download route wasn't pointed at the catalog's bumped latestVersion | The catalog bump and the zip upload must ship together — see this repo's release procedure |
| Direct link to a product's zip works without login | Storage bucket is public instead of private | Store releases in a private bucket; authorize each request server-side |
| A digital-store build "works" in dev but leaks files in prod | Authorization checked client-side only (a hidden download button) | Enforce entitlement checks in the request handler, not the UI |
Frequently asked questions
Is a digital store the same as a marketplace? No — a marketplace (Gumroad, Etsy) is one way to run a digital store. An owned storefront selling the same kind of product is another, with a different cost and a different amount of control.
Do I need a database to run a digital store? For a single product with no licensing tiers, not necessarily — a checkout provider's built-in delivery can cover it. Once you have multiple products and entitlement tiers (single-item, bundle, all-access), you need a persistent entitlement record somewhere, which usually means a database.
What's the minimum a digital store needs beyond a payment processor? A record of what each buyer owns, and a way to check that record before handing over the file. Everything else — product pages, SEO, a dashboard — is what turns a payment processor into a storefront.
Can a digital store sell templates the way this one does? Yes — that's what this codebase is: 111 Next.js/Tailwind/React templates sold as versioned zips, gated by the entitlement engine described above.
Templates in this post
ASoc Beacon is a mobile-device-management marketing site with a device-console dashboard mock, three-step enrolment, and a security/incident-response section. ASoc Beaker is a science-lab services site with a precision-science hero, a capabilities matrix, and two pricing tiers. ASoc Blueprint is an app-development agency site with a five-service offering, featured case studies, and per-project/monthly pricing.
Browse the full sets: Next.js landing page templates, Tailwind landing page templates.
