Oolvay is optimized for Vercel. MDX compilation, PostHog request proxying, Sentry source map uploads, remote image host configuration, and scheduled cron jobs are all wired into the build pipeline automatically. Once environment variables are configured, a production-grade deployment requires no manual platform setup beyond importing the repository and clicking deploy.
This page covers project creation, what happens at build time, the two scheduled jobs that ship with the framework, and a post-deployment smoke test checklist.
Before deploying, ensure the following are in place.
Sign in to Vercel and create a new project.
Import your GitHub repository. Vercel automatically detects Next.js and applies the correct build settings. No manual build configuration is required.
Every pull request automatically receives its own preview deployment. Preview and production environments are fully isolated, so each can use different credentials without any code changes.
Configure your environment variables under Project Settings. Set separate values for Preview and Production environments where credentials differ.
Deploy the project. Vercel runs bun run build, which runs bunx fumadocs-mdx to compile all MDX content, followed by the full Next.js production build. No additional MDX configuration is required.
Run database migrations against your production database. Your local and development databases already have the schema applied, but the Neon production database starts empty and needs migrations run against it before the application can function.
0 / 2,000 characters
bun db:migratePerform a smoke test. See the checklist at the end of this page.
Oolvay ships with two cron jobs registered in vercel.json, both invoked by Vercel on a fixed schedule with no additional configuration required.
| Route | Schedule | Purpose |
|---|---|---|
/api/payments/cron/reconcile | Daily at midnight UTC | Re-processes failed webhook events from the past 24 hours |
/api/notifications/cron/cleanup | Daily at 3 AM UTC | Removes expired read notifications |
Both routes are protected by CRON_SECRET. Vercel attaches this automatically as a bearer token on every scheduled invocation.
PostHog request rewrites are always registered regardless of whether PostHog is enabled. They proxy analytics traffic through your own domain to improve compatibility with ad blockers.
{
source: "/ingest/static/:path*",
destination: `${posthogAssetHost}/static/:path*`,
},
{
source: "/ingest/:path*",
destination: `${posthogHost}/:path*`,
},Sentry integration is conditional. Source map uploads, release creation, and release finalization only occur when SENTRY_AUTH_TOKEN is present and is not the dummy CI value.
const hasSentryToken =
!!process.env.SENTRY_AUTH_TOKEN && process.env.SENTRY_AUTH_TOKEN !== "dummy"
const sentryEnabled =
hasSentryToken && !!process.env.SENTRY_ORG && !!process.env.SENTRY_PROJECTWhen sentryEnabled is true, the build uploads source maps, creates and finalizes a release, and configures a tunnel route at /monitoring to route browser error reports through your own domain rather than directly to Sentry's ingest endpoint.
Sentry's automaticVercelMonitors option is enabled in next.config.ts but
does not yet work with App Router route handlers. Cron monitor instrumentation
is currently a no-op for this project.
Bundle analysis is disabled by default. Set ANALYZE=true in your build environment to generate a bundle report during the build.
const withBundleAnalyzer = bundleAnalyzer({
enabled: process.env.ANALYZE === "true",
})The following remote image hostnames are configured for next/image.
| Host | Purpose |
|---|---|
lh3.googleusercontent.com | Google profile images |
github.githubassets.com | GitHub assets |
s.gravatar.com, *.gravatar.com | Gravatar avatars |
cdn.auth0.com | Auth0 profile images |
| CloudFront hostname | User-uploaded assets |
The CloudFront hostname is added dynamically from NEXT_PUBLIC_CLOUDFRONT_URL and only included when that variable is set.
Run through this checklist after every production deployment.