WorkVibe
GitHub code repository
@suprsend/node-sdk, @suprsend/react, @suprsend/react-editor.
What the app does
WorkVibe sells to restaurant chains. Two people use it, so the app has two views:- Admin — the chain’s own team. They write the messages, decide which notifications exist and who they reach, and check what went out.
- User — a diner. They read their notifications in an in-app inbox and choose what they want to hear about.
How WorkVibe maps to SuprSend
One SuprSend account holds the whole product. Each restaurant chain is a workspace of its own, with its own keys, diners, templates, workflows and delivery logs. Nothing is shared between them. When you switch chain in the app, everything you see — diners, templates, workflows, logs — comes from that chain’s workspace alone.
App structure
The repository is organised like this:Run it locally
Prerequisites: Node.js 20+ and a SuprSend account. Sign up free at app.suprsend.com.Install
Create the workspaces
SUPRSEND_SERVICE_TOKEN.workvibe-emberoak and workvibe-nolans, and fills each Workspace Key in .env.local.Paste the remaining keys
<WS> is WORKVIBE_EMBEROAK or WORKVIBE_NOLANS.The signing key downloads as a file with line breaks, and an env file holds one line per value. Encode it before you paste it:Use the ready-made notifications
suprsend/. Push them and both workspaces have something to send from the first minute. Preview first, then push:Run
Add your starting data
The repo ships the notifications, not the data. Each workspace starts empty: no branding, no diners. You add both from the app, and both are stored in SuprSend.Set each workspace's brand
{{$brand.*}}, so emails carry the chain’s own name and colours instead of your SuprSend account name.In SuprSend, the brand is saved on the workspace’s default tenant. You can see it in the dashboard under Tenants → default.
The Ember & Oak brand on the workspace's default tenant
Add subscribers
all-subscribers list, which the app creates for you the first time you open this screen.A real diner would sign up in the chain’s own product. Add subscriber stands in for that signup.Check it works
- In Admin → Workflows, click Send test on
order-readyand pick a subscriber. - Switch to User in the top bar, pick that person in Viewing as, and open Inbox. The message is there.
- Executions shows the same send from the admin side.
Optional: welcome people when they sign up
One workflow,welcome-diner, runs on its own when someone joins the all-subscribers list. It stays quiet until you switch on the event that starts it, and that switch lives on the list itself.
In the SuprSend dashboard, open Lists, open all-subscribers, and turn on Track user entry.
Lists and Users are separate sections of the dashboard. Users is every person in the workspace; Lists is the groups they belong to. This setting lives on the list, not on the person.
- Lists
- Users

Lists — open all-subscribers here to turn on Track user entry
App navigation
Top bar
Admin view
- Templates
- Template editor
- Workflows
- Lists
- Broadcast
- Executions
- Analytics
- Users
- Preference defaults
- Brand Settings

User view
- Inbox
- Preferences

How each screen talks to SuprSend
The path every screen takes
SuprSend’s backend APIs authenticate with the workspace key and secret, and those can’t sit in browser code where anyone can read them. So every call runs on the server: open Users, the browser asks the WorkVibe server for/api/users, and that route calls SuprSend and returns the result.
For you that means all SuprSend code lives in app/api and lib/server, and the screens only ever call the app’s own routes. The exception is SuprSend’s browser components — the diner’s inbox and the template editor — which call SuprSend themselves using a short-lived token the server signs for them.
Which API each screen uses
Every route resolves the active workspace first, from thewv_workspace cookie. With no cookie, the first connected workspace is used.
Two calls that use the REST API
- List members and user preferences: both come from the REST API, called directly from
lib/server/. Use the same approach when you need them. - Preference categories: there is no call that updates one category. The save takes the whole category structure, so the app reads what is live, applies your one change to it, and sends all of it back. Changing a single toggle this way leaves every other category as it was.
How the inbox and editor get their token
Send test and Broadcast
These are the two screens that deliver a real message. Both prepare the request before it reaches SuprSend.- Send test fills every template variable from the template’s own sample data before sending, so the message renders fully even when you pass nothing. The recipient needs an email on their profile.
- Broadcast sends on a promotional category, which is where a message to everyone belongs. That keeps transactional and system categories free for the messages people are waiting on.
Publishing from your own code
POST /api/templates and POST /api/workflows (mode: "publish") publish a template or a workflow. The workflow route publishes that workflow’s templates first and stops if one fails, so a half-published journey never goes live. The screens read from SuprSend rather than publish to it, so these two are yours to call from a script or your own backend.
Change or extend it
Add a customer workspace
No code change.- Create the workspace in the dashboard.
- Add its keys to
.env.local. The prefix comes from the slug:workvibe-foo→SUPRSEND_WORKVIBE_FOO_…. - Restart the dev server. The app reads the workspace list once per process.
- To give it notifications, add
suprsend/workvibe-foo/and runnpm run push:assets -- workvibe-foo.
Edit templates, workflows or categories
Edit the files insuprsend/<workspace>/, then push. Push one workspace by naming it:
workflow or category instead of template to pull those.
Fire a workflow from the terminal
distinct_id from Users.
Check your changes
Deploy
The app runs anywhere Next.js runs, for example Vercel. Add the same variables from.env.local to the deployment, and set NEXT_PUBLIC_APP_URL to the deployed URL.
Put a password on it. WorkVibe has no login. Set DEMO_PASSWORD and every page and API route asks for it (proxy.ts). A deployed demo reads and writes your real SuprSend account.
Reusing this pattern in your own product
Two routes sign the tokens that SuprSend’s browser components need. WorkVibe has no login, so both hand a token to whoever asks. Your product knows who is signed in, so tie both to that session before you ship them.Troubleshooting
"No workspace connected"
"No workspace connected"
SUPRSEND_<WS>_WORKSPACE_KEY matches its UID and _WORKSPACE_SECRET is set. Fix the keys, then restart the dev server."Couldn't read your workspaces"
"Couldn't read your workspaces"
SUPRSEND_SERVICE_TOKEN is wrong or expired. Create a new one in Account Settings → Service Tokens."The welcome is off." on the Users screen
"The welcome is off." on the Users screen
all-subscribers has Track user entry off. Turn it on in the dashboard. People added while it was off are not welcomed.Inbox or template editor doesn't load
Inbox or template editor doesn't load
signing_key_… UID, not the ws_signk_… ID, and base64-encoded the PEM on one line.Error: “public key not configured”. NEXT_PUBLIC_SUPRSEND_<WS>_PUBLIC_KEY is empty for this workspace.Send test or editor preview fails
Send test or editor preview fails
Broadcast: "isn't a promotional category"
Broadcast: "isn't a promotional category"
offers. Ember & Oak ships with none, so add one in Preference defaults or the dashboard first.Sent, but no email arrives
Sent, but no email arrives
Preferences show email only, no inbox
Preferences show email only, no inbox
user_inbox_preference_enabled is off. npm run push:assets turns it on. If you pushed categories another way, set it with the Management API workspace config.My dashboard template edits disappeared
My dashboard template edits disappeared
npm run push:assets overwrote them. Pull before you push — see Edit templates, workflows or categories.Hosted demo returns "Locked. Enter the demo password first."
Hosted demo returns "Locked. Enter the demo password first."
DEMO_PASSWORD is set. Enter it on the gate page.











