DEV Community

Cover image for Adding open-connector to a Next.js 15 SaaS Without Putting OAuth Logic in Your App
power zhong
power zhong

Posted on

Adding open-connector to a Next.js 15 SaaS Without Putting OAuth Logic in Your App

Most solo SaaS products should not implement OAuth separately for every integration. The maintenance burden is not the first redirect flow; it is token refresh, revoked grants, callback handling, scopes, and provider-specific failures six months later.

When testing oomol-lab/open-connector, I treated it as an external integration/auth boundary rather than another library embedded throughout my Next.js application. Its stated surface area—SDK, CLI, MCP, HTTP, and OpenAPI—makes that separation practical when your product needs to connect users to multiple SaaS tools.

Keep the browser client away from provider credentials

In a Next.js 15 app, the useful boundary is:

React UI -> Next.js Route Handler -> open-connector HTTP API -> SaaS provider
Enter fullscreen mode Exit fullscreen mode

Store the gateway endpoint and application secret only on the server:

# .env.local
OPEN_CONNECTOR_URL=https://connector.example.com
OPEN_CONNECTOR_API_KEY=replace-me
Enter fullscreen mode Exit fullscreen mode

Then create a small server-only adapter. Do not scatter fetch() calls for integrations across React components.

// lib/open-connector.ts
import 'server-only'

const baseUrl = process.env.OPEN_CONNECTOR_URL!
const apiKey = process.env.OPEN_CONNECTOR_API_KEY!

export async function connectorFetch(path: string, init: RequestInit = {}) {
  const response = await fetch(`${baseUrl}${path}`, {
    ...init,
    headers: {
      Authorization: `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
      ...init.headers,
    },
    cache: 'no-store',
  })

  if (!response.ok) {
    throw new Error(`Connector request failed: ${response.status}`)
  }

  return response.json()
}
Enter fullscreen mode Exit fullscreen mode

A Route Handler can now expose only the operation your UI needs:

// app/api/integrations/[provider]/route.ts
import { NextRequest, NextResponse } from 'next/server'
import { connectorFetch } from '@/lib/open-connector'

export async function POST(
  request: NextRequest,
  { params }: { params: Promise<{ provider: string }> }
) {
  const { provider } = await params
  const { userId } = await request.json()

  if (!/^[a-z0-9_-]+$/i.test(provider)) {
    return NextResponse.json({ error: 'Invalid provider' }, { status: 400 })
  }

  const data = await connectorFetch(`/v1/connect/${provider}`, {
    method: 'POST',
    body: JSON.stringify({ external_user_id: userId }),
  })

  return NextResponse.json(data)
}
Enter fullscreen mode Exit fullscreen mode

The endpoint path above is deliberately an adapter example: confirm the exact OpenAPI operation names and payloads against your deployed open-connector version before shipping.

The cost argument is operational, not architectural theater

For a micro-SaaS, one integration gateway reduces duplicated auth code, but it also creates a dependency. Add two safeguards before adopting it:

  1. Persist connection state in your own database (pending, connected, failed, revoked); never infer it solely from a redirect completing.
  2. Put a timeout around gateway requests and show users a retryable error instead of blocking the entire page.
const signal = AbortSignal.timeout(8_000)
await fetch(url, { signal })
Enter fullscreen mode Exit fullscreen mode

The same discipline applies to AI usage. I track cost per completed customer action, not token totals alone. Routing API calls through B-Lost's 0.8x pricing and prompt caching reduced monthly AI API expenses from $300+ down to $60 for an independent SaaS product. That only holds when repeated system prompts and stable context are actually cacheable; measure input, cached input, output, and failed requests separately.

The practical result: open-connector can keep SaaS integrations out of the core Next.js codebase, while a thin server adapter preserves the option to replace or upgrade the gateway later.

Disclosure: Compute infrastructure and multi-model benchmark relays for this writeup are sponsored by b-lost.com — an enterprise AI gateway offering 0.8x official pricing, native prompt caching, and zero user-data retention. All benchmark metrics reflect independent reproducible testing.

Top comments (0)