> ## Documentation Index
> Fetch the complete documentation index at: https://bundleup.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Next.js Quickstart

> Connect your first integration with a Next.js app using the BundleUp JavaScript SDK.

This guide builds the [Quickstart](/docs/quickstart) flow into a Next.js app with the BundleUp JavaScript SDK. A user clicks **Connect GitHub**, authorizes on GitHub, and lands back in your app, which exchanges the one-time `code` for a `connection_id` and lists their repositories through the [Unified API](/docs/guides/unified/overview).

```mermaid theme={null}
sequenceDiagram
    participant U as End user
    participant App as Your Next.js app
    participant BA as BundleUp Auth
    participant GH as GitHub

    U->>App: Click "Connect GitHub"
    App-->>U: Redirect to auth.bundleup.io/authorize
    U->>BA: client_id, integration_id, redirect_uri
    BA-->>U: Redirect to GitHub consent
    U->>GH: Approve
    GH-->>BA: Authorization code
    BA-->>U: Redirect to /callback?code=...
    U->>App: GET /callback?code=...
    App->>BA: POST /connection (API key, code)
    BA-->>App: connection_id
    App->>App: List repos via the Unified API
```

## Prerequisites

* Node.js 18+ installed.
* In the BundleUp dashboard, complete steps 1 to 3 of the [Quickstart](/docs/quickstart):
  * a **GitHub integration** with the identifier `github`,
  * `http://localhost:3000/callback` registered under **Auth → Redirect URIs**,
  * an **API key**, and your **Client ID** from the **Auth** page.

## 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:

<CodeGroup>
  ```shellscript npm theme={null}
  npm create next-app@latest bundleup-nextjs -- --yes
  cd bundleup-nextjs
  npm install
  ```

  ```shellscript pnpm theme={null}
  pnpm create next-app bundleup-nextjs --yes
  cd bundleup-nextjs
  pnpm install
  ```

  ```shellscript yarn theme={null}
  yarn create next-app bundleup-nextjs --yes
  cd bundleup-nextjs
  yarn install
  ```

  ```shellscript bun theme={null}
  bunx create-next-app bundleup-nextjs --yes
  cd bundleup-nextjs
  bun install
  ```
</CodeGroup>

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`.

<CodeGroup>
  ```shellscript npm theme={null}
  npm install @bundleup/sdk
  ```

  ```shellscript pnpm theme={null}
  pnpm add @bundleup/sdk
  ```

  ```shellscript yarn theme={null}
  yarn add @bundleup/sdk
  ```

  ```shellscript bun theme={null}
  bun add @bundleup/sdk
  ```
</CodeGroup>

You'll use this SDK later to fetch data from GitHub through the BundleUp 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:

```bash .env.local lines theme={null}
# 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

# Must exactly match a redirect URI registered in your BundleUp dashboard
NEXT_PUBLIC_BUNDLEUP_REDIRECT_URI=http://localhost:3000/callback
```

<Warning>
  Your **API key** must remain server-side only. Never expose it in client-side code or environment variables prefixed with `NEXT_PUBLIC_`.
</Warning>

## Step 4: Create the authorization link

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`)

```typescript app/page.tsx lines theme={null}
import { BundleUp } from "@bundleup/sdk";

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

export default function Home() {
  const url = client.auth.buildAuthorizationUrl({
    clientId: process.env.NEXT_PUBLIC_BUNDLEUP_CLIENT_ID!,
    integrationId: process.env.NEXT_PUBLIC_BUNDLEUP_INTEGRATION_ID!,
    redirectUri: process.env.NEXT_PUBLIC_BUNDLEUP_REDIRECT_URI!,
  });

  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 one-time `code`.

The `code` is not the connection. Your server exchanges it, using your API key, for a `connection_id`. The code expires after 5 minutes and can only be used once.

The `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`), exchange the code, and use the SDK to fetch data:

```typescript app/callback/page.tsx lines theme={null}
import { BundleUp } from "@bundleup/sdk";

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

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

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

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

  // Exchange the one-time code for the connection (server-side only)
  const { connection_id } = await client.auth.getConnectionFromCode({
    code,
    redirectUri: process.env.NEXT_PUBLIC_BUNDLEUP_REDIRECT_URI!,
  });

  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>
  );
}
```

<Note>
  `redirectUri` must be exactly the same value you used to start the flow. BundleUp rejects the exchange otherwise.
</Note>

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:

```bash theme={null}
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.

## Next steps

* **Store the `connection_id`** against the signed-in user in your database, and reuse it. Don’t send the user through the flow again.
* **Pass a `state` value** when you build the authorization URL and check it in the callback, to protect against CSRF. See [Connecting user accounts](/docs/guides/auth/authorization-flow#protect-the-flow-with-state).
* **Pass an `external_id`** (your user ID) so you can find connections by user later.
* **Call the provider directly** through the [Proxy](/docs/guides/proxy/overview) when you need something the Unified API doesn’t cover.
* See the full [JavaScript SDK reference](/docs/sdks/javascript).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.