apps/api (Pylon backend) and apps/web (Next.js frontend), ready to deploy. apps/web/next.config.js already proxies /api/* to the backend on :4321.
1. Deploy the backend to Pylon Cloud
Sign in at www.pylonsync.com, create an organization, and connect the GitHub repo. The setup wizard provisions a Fly Machine, points it atapps/api/app.ts, and gives you a default hostname:
main), and Pylon Cloud deploys it automatically.
You can also add a custom domain (api.example.com) in the project’s Domains tab. We recommend this once you go live, because it keeps the URL stable across project renames.
2. Deploy the frontend to Vercel
Create a Vercel project pointed at the same GitHub repo. In Project Settings → Build & Development Settings:- Framework Preset: Next.js (auto-detected)
- Root Directory:
apps/web - Install Command:
bun install(or your package manager) - Build Command:
next build
apps/web/next.config.js automatically.
3. Set the backend URL
In Project Settings → Environment Variables, add:
The Next.js template’s
next.config.js rewrites /api/* to ${PYLON_TARGET}/api/*, so the browser always talks same-origin to Vercel, and Vercel forwards the request to your Pylon backend. This is the recommended pattern: it avoids CORS preflight requests and lets the session cookie work without cross-site cookie settings.
For local dev (bun run dev), PYLON_TARGET defaults to http://localhost:4321 so no .env.local is required when your backend is pylon dev on the same machine.
4. Configure CORS (only if you skipped the rewrite)
If your Next.js rewrite proxies/api/*, you do not need CORS. The browser only sees the Vercel origin.
If your frontend talks to Pylon Cloud directly (fetch("https://api.example.com/api/fn/...") from the browser), open your project’s Settings → CORS tab on Pylon Cloud and add your Vercel deployment URLs:
5. Push and verify
- Vercel build: takes about 30 seconds. Watch the deploy log for the build step.
- Pylon Cloud deploy: runs in parallel. Check the project’s Deployments tab.
/api/* requests succeeding (status 200, Set-Cookie header on auth endpoints).
Cookie checklist
If session cookies are not sticking, work through this list:- Cookie name matches. Pylon emits
${app_name}_session. YourcreatePylonServer({ cookieName })andcreatePylonProxy({ cookieName })must pass the same name. A mismatch causes silent 401 errors. - Same-site defaults to Lax. Pylon defaults to
SameSite=Lax, which works with Next.js’s same-origin pattern. If you must use cross-site cookies (skipping the rewrite), setPYLON_COOKIE_SAME_SITE=NoneandPYLON_COOKIE_SECURE=true. - Domain matches. If the frontend is
app.example.comand the backend isapi.example.com, setPYLON_COOKIE_DOMAIN=.example.comso the cookie applies to both subdomains. Do not set this if you are using the rewrite pattern; host-only cookies are tighter. - iOS Chrome and Safari. iOS browsers reject domain-scoped cookies when a host-only cookie of the same name is present. Pylon v0.3.140+ handles this by pairing every domain-scoped set with a host-only
Max-Age=0clear. Make sure your Pylon backend is on a recent framework version.
Custom domain end-to-end
- Pylon Cloud project domains:
api.example.com - Vercel project domains:
app.example.com - Vercel env var:
PYLON_TARGET=https://api.example.com - Your
next.config.jsrewrite continues to forward/api/*to${PYLON_TARGET}/api/*
app.example.com.
Troubleshooting
Build fails: “Module not found: @pylonsync/next”. You are probably building from the repo root instead ofapps/web. Set Vercel’s Root Directory to apps/web.
Too many requests. Limit: 100 per 60s from the dashboard. Pylon defaults to 100 requests/min per authenticated user. Raise it with PYLON_RATE_LIMIT_MAX_AUTHED (default 1000 since v0.3.148) on your Pylon Cloud project.
PYLON_BACKEND_UNREACHABLE errors in Next.js logs. Your Pylon Cloud machine is stopped (autostop after idle) or restarting. The server helpers time out after 5s, and an error.tsx boundary makes this graceful. Restart the machine from the project’s Overview tab.
Live queries do not update across tabs. The sync engine WebSocket may be misrouted. Check that PYLON_TARGET resolves, and that your browser’s WebSocket connection (DevTools → Network → WS) connects to wss://<your-target>/api/sync successfully.
Next steps
Custom domains
Wire DNS for your Pylon Cloud project.
Cookie & sessions
Full cookie config reference.
Next.js SDK
All
@pylonsync/next APIs.Pylon Cloud
Project management, scaling, custom domains.