Skip to content

Draft mode

Draft Mode

When to Use

Enable content editors to preview unpublished content and revisions in an iframe within Drupal before publishing.

Steps

1. Create OAuth consumer in Drupal

Follow Authentication Patterns to create an OAuth consumer with: - Scope: Role with "Bypass content access control" permission - Grant type: Client Credentials

2. Create Next.js site in Drupal

Visit /admin/config/services/next: - Label: Next.js - Base URL: http://localhost:3000 - Draft URL: http://localhost:3000/api/draft - Preview secret: Generate a secure token

3. Create draft API route

// app/api/draft/route.ts
import { drupal } from "@/lib/drupal"
import { enableDraftMode } from "next-drupal/draft"
import type { NextRequest } from "next/server"

export async function GET(request: NextRequest) {
  return enableDraftMode(request, drupal)
}

4. Create disable-draft API route

// app/api/disable-draft/route.ts
import { disableDraftMode } from "next-drupal/draft"
import type { NextRequest } from "next/server"

export async function GET(request: NextRequest) {
  return disableDraftMode()
}

5. Configure environment variables

DRUPAL_CLIENT_ID=your-oauth-client-id
DRUPAL_CLIENT_SECRET=your-oauth-secret
DRUPAL_PREVIEW_SECRET=your-preview-secret

6. Update NextDrupal client for auth

export const drupal = new NextDrupal(baseUrl, {
  auth: {
    clientId: process.env.DRUPAL_CLIENT_ID,
    clientSecret: process.env.DRUPAL_CLIENT_SECRET,
  },
})

7. Configure content types for preview

Visit /admin/config/services/next/entity-types: - Click "Configure entity type" - Select content type (e.g., Article) - Draft Mode tab: Select "Site selector" plugin - Select your Next.js site - Save

Decision Points

Decision When Impact
Secret generation Setup Use cryptographically secure random string
OAuth scope permissions Setup Must include "Bypass content access control"
Preview plugin Per content type Site selector vs custom resolver

Common Mistakes

  • Using same secret for preview and revalidation — Security issue. WHY: Separate concerns, different access levels.
  • Not validating preview secret — Security hole. WHY: enableDraftMode validates automatically, don't skip it.
  • Missing auth configuration — Preview shows 403 errors. WHY: Draft mode requires authenticated requests to fetch unpublished content.
  • Not testing with unpublished content — Doesn't verify auth works. WHY: Test with status = 0 content.

See Also

  • Authentication Patterns
  • On-Demand Revalidation
  • Security Best Practices