fotoswipe-dual-license-e2e
FotoSwipe dual‑license commercialization playbook (end‑to‑end)
Audience: solo founder shipping a commercial widget fast, with clean architecture and low ops.
Principles (from .cursorrules)
- Brand only in docs/marketing as "FotoSwipe"; keep npm names
photoswipe(AGPL) andphotoswipe-pro(commercial). - Pro features must be tree‑shakeable and license‑gated; local validation with offline grace; no hard phone‑home.
- Provider‑agnostic, SOLID/DRY; depend on small interfaces; keep secrets server‑side.
TL;DR rollout
- Day 0–1: Publish docs site Pro page, “Get License Key” CTA, trial flow scaffold. Ship license proxy and gate.
- Day 2–3: Starter kits + 2 tutorials (AI alt text; ImageObject schema). Add pricing and licensing pages.
- Day 4–7: Acceptance tests, signed releases, SBOM; pitch (Shopify/Woo/Next.js audiences).
Packaging & licensing
- Community:
photoswipeunder AGPL. Commercial boundary enforced byLICENSE-commercialanddocs/licensing.md. - Pro:
photoswipe-prodistributed via private registry or ZIP. All Pro code behind a license gate. - Keep public APIs stable; additions are backward compatible; semver both packages.
Key files
LICENSE(AGPL),LICENSE-commercial,docs/licensing.md,docs/pricing.md.- Pro gate and provider:
src/pro/license.js(local gate + offline grace)src/pro/license-remote.js(remote‑aware gate, instance caching)src/pro/licensing/LemonSqueezyProvider.js(talks to your backend)- Server proxy:
server/lemonsqueezy/router.js
- Integration details:
docs/lemon-squeezy-license-integration.md
Distribution
- Community: publish to public npm (
photoswipe). - Pro: ship to private npm (auth via license key) or GitHub Releases as ZIP.
- Maintain release notes and checksums; optionally sign releases (cosign) and attach SBOM.
Trials & licensing UX
- Trial: 7‑day key with local validation and offline grace; clear banner with days left.
- Activation: paste key, optional email check; store
instance_idandlast_validation_ts. - Validation cadence: skip while in grace; after grace, validate via proxy with backoff; fail closed gracefully with clear messaging.
Backend proxy (Lemon Squeezy)
- Endpoints:
/api/license/{activate,validate,deactivate}; seeserver/lemonsqueezy/router.js. - Verify
store_idand product/variant IDs; keepLEMON_SQUEEZY_*secrets server‑side only. - Docs:
docs/lemon-squeezy-license-integration.md.
Docs/marketing
- Pro landing:
demo-docs-website/src/pages/pro.mdxwith live demo and license panel (src/components/LicensePanel.js). - CTAs: “Get License Key” and “Start 7‑day Trial”.
- Comparison (Free vs Pro) and quick starts for Shopify/Woo/Next.js.
Support & legal
SUPPORT.mdfor priority email support (Pro).LICENSE-commercialterms (domains, seats, SLA for enterprise); keep copy congruent with docs.
QA & acceptance tests
- Test licensed/unlicensed states: active/inactive/expired/disabled, offline grace, error paths, deactivation.
- Mock provider to avoid external dependencies; fixtures for proxy responses.
Security & privacy
- No secrets in the browser; no unsolicited telemetry. If enabled, anonymized and opt‑in.
- Respect accessibility and SEO constraints; server‑render schema where applicable.
Release hygiene
- Semver tags; changelog updates; signed artifacts and SBOM linked in releases.
What’s already in this repo
- Gate and local validation:
src/pro/license.js. - Remote‑aware gate and provider scaffold:
src/pro/license-remote.js,src/pro/licensing/LemonSqueezyProvider.js. - Proxy router example:
server/lemonsqueezy/router.js. - Docs site Pro page + license panel:
demo-docs-website/src/pages/pro.mdx,demo-docs-website/src/components/LicensePanel.js. - Command reference:
docs/commands.md.
Setup steps (end‑to‑end)
1) Install deps: npm install && cd demo-docs-website && npm install.
2) Configure env (server): LEMON_SQUEEZY_API_KEY, LEMON_SQUEEZY_STORE_ID, and product/variant ID.
3) Mount proxy under /api/license (Express or serverless) using server/lemonsqueezy/router.js.
4) Wrap Pro entry with withRemoteAwareGate and inject new LemonSqueezyProvider({ baseUrl: '/api/license' }).
5) Run everything: npm run watch (or npm run watch-js, npm run watch-css, and docs server on an open port).
6) Validate UX in /pro page: activate, validate, deactivate flows; verify mocked mode when backend is absent.
7) Publish pricing and licensing docs; wire CTAs on the Pro page.
Go‑to‑market checklist
- Pricing and tiers finalized (
docs/pricing.md), with license boundary copy indocs/licensing.md. - Landing with demo and CTAs live; announce via tutorials and starter kits.
- Trial keys working end‑to‑end; email support configured.
- Acceptance tests and release integrity (signing/SBOM) in place.