# Workflow: SDK Preview Mode

## Purpose

Enable dashboard preview editing for an SDK-hosted Next.js site. Preview mode lets the dashboard open the external site with a short-lived editor session, render draft content, and show the Riverbank preview shell.

## Prerequisites

- A Riverbank SDK site using the Next.js App Router.
- A preview/staging URL for the site.
- A Riverbank preview API key (`bld_preview_sk_...`) for draft content.
- Dashboard access to run `riverbankcms push-config`.

## Configure `riverbank.config.ts`

Set the preview URL and enable token-based preview editing:

```ts
import { defineConfig } from '@riverbankcms/sdk/config'

export default defineConfig({
  siteId: process.env.RIVERBANK_SITE_ID!,
  previewUrl: process.env.NEXT_PUBLIC_SITE_URL!,
  dashboard: {
    previewEditingEnabled: true,
  },
})
```

Then sync the config:

```bash
riverbankcms push-config --env=remote
```

Use `--dashboard <url>` and `--api-key <key>` when you want explicit values to override environment variables.

## Add Preview Token Proxy

Create `src/proxy.ts`:

```ts
import { handlePreviewTokens } from '@riverbankcms/sdk/preview-next/middleware'
import { NextResponse, type NextRequest } from 'next/server'

export function proxy(request: NextRequest) {
  if (process.env.RIVERBANK_PREVIEW_MODE === 'true') {
    const response = handlePreviewTokens(request)
    if (response) return response
  }

  return NextResponse.next()
}

export const config = {
  matcher: ['/((?!_next/static|_next/image|api|favicon.ico|robots.txt|sitemap.xml).*)'],
}
```

## Add Preview Keep-Alive Route

Create `src/app/api/preview/keep-alive/route.ts`:

```ts
import type { NextRequest } from 'next/server'

import { createPreviewKeepAliveRouteHandler } from '@riverbankcms/sdk/preview-next/keep-alive'

const handler = createPreviewKeepAliveRouteHandler()

export function GET(request: NextRequest) {
  return handler(request)
}

export function POST(request: NextRequest) {
  return handler(request)
}
```

## Add The Client Preview Wrapper

Create `src/components/preview/SdkPreviewModeClient.tsx`:

```tsx
'use client'

import { PreviewQueryProvider, SdkPreviewMode, type SdkPreviewModeProps } from '@riverbankcms/sdk/preview-next/client'

import { blockOverrides } from '@/lib/block-overrides'

type SdkPreviewModeClientProps = Omit<SdkPreviewModeProps, 'blockOverrides'>

export function SdkPreviewModeClient(props: SdkPreviewModeClientProps) {
  return (
    <PreviewQueryProvider>
      <SdkPreviewMode {...props} blockOverrides={blockOverrides} />
    </PreviewQueryProvider>
  )
}
```

## Wire The Catch-All Page

Use `createPreviewModeBeforeRender` in the catch-all page:

```tsx
import { createCatchAllPage } from '@riverbankcms/sdk/next'
import { createPreviewModeBeforeRender } from '@riverbankcms/sdk/preview-next/before-render'

import config from '../../../riverbank.config'
import { blockOverrides } from '@/lib/block-overrides'
import { getRiverbankClient } from '@/lib/riverbank-client'
import { SdkPreviewModeClient } from '@/components/preview/SdkPreviewModeClient'

const { Page, generateMetadata } = createCatchAllPage({
  getClient: getRiverbankClient,
  config,
  blockOverrides,
  beforeRender: createPreviewModeBeforeRender({
    getClient: getRiverbankClient,
    siteId: config.siteId,
    PreviewModeClient: SdkPreviewModeClient,
  }),
})

export default Page
export { generateMetadata }
```

## Import Preview CSS

For Tailwind sites, add this to `src/app/globals.css`:

```css
@import "tailwindcss";
@import "@riverbankcms/sdk/preview-next/tailwind-sources.css";
@import "@riverbankcms/sdk/preview-next/chrome.css";
```

For non-Tailwind sites, use the legacy single import:

```css
@import "@riverbankcms/sdk/preview-next/styles.css";
```

## Environment Variables

For Vercel preview or any external preview host:

```bash
RIVERBANK_PREVIEW_MODE=true
RIVERBANK_ENV=remote
RIVERBANK_REMOTE_SITE_ID=...
RIVERBANK_REMOTE_DASHBOARD_URL=https://...
RIVERBANK_REMOTE_PREVIEW_API_KEY=bld_preview_sk_...
```

Use a preview API key when `RIVERBANK_PREVIEW_MODE=true`; content/live keys cannot read draft content. Keep the management API key (`RIVERBANK_REMOTE_MGMT_API_KEY`) for CLI sync commands such as `push-config`, not for public rendering.

## Verification

1. Run `riverbankcms push-config --env=remote`.
2. Build the site with `RIVERBANK_PREVIEW_MODE=true`.
3. Open the dashboard preview button.
4. Confirm the URL starts at `previewUrl`.
5. Confirm the preview shell loads and editable content appears.
6. Confirm `/api/preview/keep-alive` returns without authentication errors during the session.
