Welcome to Vanilla Breeze
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
This bell pulls live notifications from /go/notify/messages — the same contract documented at /docs/concepts/service-contracts/. Static articles like this one are the no-JS / no-backend fallback.
VB's reserved URL namespace for service relay endpoints, GoodURL link facades, and shortlinks. One indirection layer between components and third-party services.
A single URL namespace on Vanilla Breeze sites for service relay endpoints, link facades, and shortlinks. The convention lets components stay decoupled from the concrete service behind each endpoint.
Modern web development couples components directly to third-party services. Changing email providers means hunting through every fetch('https://api.sendgrid.com/...') call in your code. Swapping search backends means touching every component that hits Algolia. The same is true for analytics, AI, payments, maps, fonts — the list keeps growing.
The /go/ convention introduces one indirection layer. Components call a stable first-party URL; the developer points that URL at whichever provider they want, server-side. Swap the implementation, leave the components untouched.
Component → VBService('email') → /go/email → [your worker] → Sendgrid | Postmark | SES | self-hosted
These slugs are reserved for VB service endpoints. They must not be used as GoodURL curated link slugs or as shortlink keywords.
| Path | Service | Purpose |
|---|---|---|
/go/notify | Notifications | Push/poll notification delivery |
/go/email | Transactional email (contact forms, watch alerts, GoodURL digests) | |
/go/feed | Content Feed | Changelog, what’s new, release notes (JSON format) |
/go/newsletter | Newsletter | Newsletter subscription management |
/go/search | Search | Site search relay (Algolia, Meilisearch, Pagefind, etc.) |
/go/ai | AI/LLM | AI chat relay (keeps API keys server-side) |
/go/chat | Chat | Live chat relay (Intercom, Crisp, custom) |
/go/webhook | Webhooks | Incoming webhook receiver |
/go/auth | Authentication | OAuth/session management relay |
/go/analytics | Analytics | First-party analytics endpoint |
/go/storage | Storage | File upload/asset management relay |
| Path | Purpose |
|---|---|
/rss | RSS/Atom feed (root-level, not under /go/) |
/p/{id} | GoodURL permalink system — permanent page identifiers |
When a request arrives at /go/{slug}, the router resolves in this order:
Reserved names always win. The reserved list is a small, finite set; checking it first is fast. Service endpoints respond with application/json on a 200; facades respond with a 301 redirect — same namespace, different response shape based on the slug.
The client side of the convention is VBService. Components instantiate by role name; VBService.resolve() maps the role to a URL, defaulting to /go/{role}.
import { VBService } from './lib/vb-service.js'; const notify = new VBService('notify');await notify.get('/messages');// GET /go/notify/messages// ─── because baseUrl defaults to '/go' and the role is 'notify' VBService.resolve('email'); // '/go/email'VBService.resolve('search'); // '/go/search'/code-block <p>Two override hooks. <code>baseUrl</code> moves every service under a different prefix:</p> <code-block language="js" label="Move every service to /api/" data-escape="">VBService.configure({ baseUrl: '/api' });VBService.resolve('email'); // '/api/email'/code-block <p><code>services</code> overrides individual roles — useful when one service points at a third-party host directly:</p> <code-block language="js" label="Per-service override" data-escape="">VBService.configure({ services: { ai: 'https://api.openai.com/v1', },});VBService.resolve('ai'); // 'https://api.openai.com/v1'VBService.resolve('email'); // '/go/email' (still default)/code-block
/go/ is short, memorable, and verb-like — “go do this thing for me.” It doubles as the home for outbound link management (GoodURL facades) and shortlinks, so a single namespace covers services, facades, and redirects without needing parallel prefixes. It won’t collide with content the way /api/ can on sites that already serve an API, or the way /services/ can on sites that have an org page. Go-links at Google, Slack, and many organizations set the precedent.
Vanilla Breeze ships the convention, the client (VBService), and JSON contracts. The developer ships whatever lives behind each /go/ endpoint — a Cloudflare Worker, an Express route, a Lambda, a static file. VB stays agnostic about the backend on purpose.
VBService.configure({ services }) when one role lives somewhere other than your own /go/ prefix.JSON request/response schemas for every /go/ endpoint — the contract a backend must fulfil.
The general pattern /go/ specialises — first-party endpoints that proxy third-party services.
Reads /go/notify via VBService for dynamic notifications and the panel-mode unread badge.
Other architectural choices and the failure modes they prevent.