But it got me thinking…
If I shared the entire process here would you follow along?
The very minimal app so far is running on a Cloudflare Worker, using their accurately named "Quick edit" feature. It's probably time to learn how their proper CLI works so I can have more than one Javascript file…
Let's build the part the SaaS' customer logs in to. Since this app's entire purpose is to hook up to your Stripe, and since this walkthrough's entire purpose is to show how minimally we can SaaS… let's use Stripe for login instead of managing our own
I'm not even going to store anything server-side for now. Just Stripe OAuth → store what we need in a JWE (encrypted JSON Web Token) cookie
I know, I know, I'm basically MacGyver
👏 @CloudflareDev
[*] shh that is literally how DNS works
And then arrow functions… and async/await…
10 years ago I was saying how beautiful C# was as a language - it was just let down by the APIs it was generally used with (.NET)
Modern JS might be the whole package (…except typing)
Obvious option would be Cloudflare Workers KV, but…
Going to give Google Cloud Firestore/Datastore a shot instead.
1) this one is really quick and cheap and fun to build
2) my primary goal here is to show how true #1 is, not to #bizniss
Sure I could've gone all-out research mode… customer development… pain points…
But today I'd rather hack around for a few hours and share and have fun and see what happens ¯\_(ツ)_/¯
- Cancellation (remove access and disable links when customer cancels through the Billing Portal)
- The page where they actually create their product links
- DESIGN
- A domain & a production environment
…
I think the best way round this is to just store the customer ID as well as the account ID in our Datastore when they first subscribe.
Have I mentioned how insanely great @tailwindcss is (and by extension @adamwathan and @steveschoger)?
- Cloudflare Worker listener is called
- Check the URL path. In this case it's /admin/products
- Check they're logged in and subscribed
products = [
{ id, prices: [
{ id, name, price },
…
],
…
]
- We pass that nice data block to our view. Liquid templating like {% for price in prices %} handles rendering the data
You can login (using Stripe). You can subscribe. You then get shown a list of all your Stripe products, with a checkout link for each. You can copy those links and send them to people. Those people get taken to a…
Spent some time the other day trying to come up with a suitable name. And I'm now proud to present…
shutupandtakemymoney.app
Depressing because the mind starts counting how many hours you (and the world) have ever spent fighting AWS (cc @QuinnyPig @mike_julian)
- Add the domain to CF
- Add [env.production] to your wrangler.toml, along with the domain and Zone ID from CF
- wrangler publish --env production
- Set the production env vars
What have I become
Friction is high.
Are there easy ways to lower it? A couple of things jump out…
The aim is to SHOW THEM AS MUCH AS POSSIBLE while they PROVIDE AS LITTLE AS POSSIBLE.
So, what might that look like for us?
(This might be the first time in the thread I've put my product hat on in place of my hacker hat. Feels good)
2) We could show screenshots of what they'd get within the app if they signed up
…
[if subscribed]
show product list
[else]
show SUBSCRIBE button
we can do
[everyone]
show product list; with big message slapped across is if not subscribed