Skip to main content
Get started with BundleUp in your Next.js application in under 5 minutes. This guide walks you through connecting to a third-party API using GitHub as an example, but the same flow applies to any supported integration. By the end of this guide, you’ll:
  • Redirect a user through an OAuth-style authorization flow
  • Receive a connection_id
  • Use that connection_id to make unified API calls via BundleUp

Prerequisites

Before you begin, make sure you have:
  • A BundleUp account
  • A BundleUp API key (server-side)
  • Your BundleUp Client ID (used for authorization redirects)
  • An Integration ID for the service you want to connect (for example, github)
  • Node.js 18+ installed
You can find your API key, Client ID, and Integration IDs in the BundleUp dashboard.

Step 1: Create a new Next.js app

If you don’t already have a Next.js project, start by creating one. BundleUp works with both the App Router and Pages Router, but this guide uses the App Router. Run one of the following commands to scaffold a new app:
npm create next-app@latest bundleup-nextjs -- --yes
cd bundleup-nextjs
npm install
Once finished, you should have a working Next.js app you can run locally.

Step 2: Install @bundleup/sdk

Next, install the official BundleUp SDK. This SDK is used server-side to make authenticated requests to third-party APIs using a connection_id.
npm install @bundleup/sdk
You’ll use this SDK later to fetch data from GitHub through BundleUp’s unified API.

Step 3: Configure environment variables

BundleUp uses two types of credentials:
  • A server-side API key for making API requests
  • A client-safe Client ID for starting the authorization flow
Create a .env.local file in your project root and add the following:
.env.local
# Server-side only - NEVER expose this in the browser
BUNDLEUP_API_KEY=your_api_key_here

# Client-side safe - used in browser for auth redirect
NEXT_PUBLIC_BUNDLEUP_CLIENT_ID=your_client_id_here
NEXT_PUBLIC_BUNDLEUP_INTEGRATION_ID=github
NEXT_PUBLIC_BUNDLEUP_REDIRECT_URI=http://localhost:3000
Your API key must remain server-side only. Never expose it in client-side code or environment variables prefixed with NEXT_PUBLIC_.
In this step, you’ll create a simple page that sends the user to BundleUp’s authorization endpoint. This URL:
  • Identifies your app (client_id)
  • Specifies which integration to connect (integration_id)
  • Defines where the user should be redirected after authorization (redirect_uri)
app/page.tsx
export default function Home() {
  const url = `https://auth.bundleup.io/authorize?
client_id=${process.env.NEXT_PUBLIC_BUNDLEUP_CLIENT_ID}
&integration_id=${process.env.NEXT_PUBLIC_BUNDLEUP_INTEGRATION_ID}
&redirect_uri=${encodeURIComponent(`http://localhost:3000/callback`)}`;

  return (
    <div className="flex items-center justify-center p-4">
      <a
        href={url}
        className="bg-blue-500 hover:bg-blue-600 text-white px-6 py-3 rounded-lg font-medium"
      >
        Connect GitHub
      </a>
    </div>
  );
}
When a user clicks Connect GitHub, they’ll be redirected to GitHub to approve access.

Step 5: Handle the callback and fetch data

After the user authorizes the integration, BundleUp redirects them back to your app with a connection_id. This connection_id represents:
  • A specific user
  • A specific integration
  • Securely stored credentials managed by BundleUp
The connection_id is stable and reusable. You should store it and reuse it for future requests instead of re-authorizing the user. Create a callback page (for example, app/callback/page.tsx) and use the SDK to fetch data:
app/callback/page.tsx
import { BundleUp } from "@bundleup/sdk";

const client = new BundleUp(process.env.BUNDLEUP_API_KEY!);

interface PageProps {
  searchParams: Promise<{
    error?: string;
    error_description?: string;
    connection_id: string;
  }>;
}

export default async function Callback({ searchParams }: PageProps) {
  const { connection_id, error, error_description } = await searchParams;

  if (error) {
    return (
      <div className="flex items-center justify-center p-4">
        <p className="text-red-600">Error: {error_description}</p>
      </div>
    );
  }

  const repos = await client.unify(connection_id).git.repos();

  return (
    <div className="flex items-center justify-center p-4">
      <p className="text-green-600">
        Successfully connected! Here are your repos:
      </p>
      <ul>
        {repos.data.map((repo) => (
          <li key={repo.id}>{repo.full_name}</li>
        ))}
      </ul>
    </div>
  );
}
At this point:
  • BundleUp handles authentication, token refresh, and API differences
  • You make a single, normalized API call

Step 6: Run your application

Start your Next.js development server:
npm run dev
Visit http://localhost:3000 and click “Connect GitHub”. You’ll be redirected to GitHub to authorize the connection. After authorization, you’ll be redirected back and can fetch your repositories.

What’s next?

  • Store the connection_id in your database
  • Use it across API routes, server actions, or background jobs
  • Add support for additional integrations with zero auth changes