---
title: "Embedding n8n in a Next.js App: The Four Levels (And What Each Costs)"
description: "Every forum thread mixes up what 'embedding n8n' means. Here are the four distinct architectures — from simple webhook dispatching and @n8n/chat widgets to the public REST API and white-label Embed licences."
canonical: "https://www.razi.pro/blog/how-to-embed-n8n-in-nextjs"
date: "2026-09-06"
tags: ["n8n", "Next.js", "Architecture", "Webhooks", "React", "Automation"]
source: "razi.pro"
---

# Embedding n8n in a Next.js App: The Four Levels (And What Each Costs)

When someone on Reddit or the n8n community forums asks *"How do I embed n8n into my Next.js web application?"*, half the replies say *"just add a webhook"*, three people mention the `@n8n/chat` npm package, and an enterprise sales rep talks about the multi-tenant Embed licence.

They are all answering completely different questions.

Before writing a single line of code, you have to separate **which kind of embedding** your product actually needs. There are four distinct levels, and choosing the wrong one will either waste months of engineering or cost you thousands in unneeded enterprise licences.

---

## The Four Levels at a Glance

| Level | What the user sees | What n8n is doing | Cost / Complexity |
|---|---|---|---|
| **Level A: Headless Pipeline** | Your bespoke Next.js UI (forms, dashboards, buttons) | Backend orchestration engine triggered by webhooks | Free / 1 day |
| **Level B: Chat Widget** | An expandable chat balloon in the bottom corner | Running an AI agent or Q&A workflow | Free / 2 hours |
| **Level C: Custom Management Portal** | Custom React dashboard showing execution history & toggles | Exposing its internal REST API (`/api/v1`) | Free / 1 week |
| **Level D: Visual Canvas Studio** | The actual drag-and-drop node graph inside your app | Running as a white-labelled, multi-tenant workflow builder | Enterprise licence / Months |

---

## Level A: Headless Pipeline (The 90% Solution)

Most developers do not actually want their end-users touching node graphs. They want a clean, responsive Next.js frontend (Tailwind, React 19, Zod validation) that kicks off a complex automation pipeline in the background.

In this architecture, **the browser never talks to n8n directly**. The browser calls your Next.js API route handler, your route authenticates the user with NextAuth or session cookies, and the server dispatches a signed webhook to your self-hosted n8n instance:

```
[User Browser]
      │  (NextAuth Session / Cookie)
      ▼
[Next.js App Router: /api/workflows/trigger]
      │  (Server-to-Server HTTPS + Shared Secret Header)
      ▼
[Self-Hosted n8n Instance (Webhook Node)]
      │
      ├───► (Immediate HTTP 200 response)
      ▼
[Downstream Multi-Step Workflow Execution]
```

### Production Next.js Route Handler

```typescript
// app/api/workflows/trigger/route.ts
import { NextRequest, NextResponse } from "next/server";
import { auth } from "@/lib/auth/auth";

export async function POST(req: NextRequest) {
  // 1. Authenticate the caller at your Next.js perimeter
  const session = await auth();
  if (!session?.user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const payload = await req.json();

  // 2. Dispatch to n8n using internal secret (never expose this in client JS)
  const n8nWebhookUrl = process.env.N8N_WEBHOOK_URL!;
  const secretKey = process.env.N8N_SHARED_SECRET!;

  const res = await fetch(n8nWebhookUrl, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-Workflow-Token": secretKey,
    },
    body: JSON.stringify({
      userId: session.user.id,
      email: session.user.email,
      ...payload,
    }),
  });

  if (!res.ok) {
    return NextResponse.json({ error: "Failed to dispatch workflow" }, { status: 502 });
  }

  const data = await res.json();
  return NextResponse.json(data);
}
```

> **Important**: Pair this with our [Async Webhook Pattern](https://www.razi.pro/blog/n8n-respond-to-webhook-without-waiting) so your Next.js route releases the connection in under 100ms instead of timing out at Vercel's 15s function ceiling.

---

## Level B: The `@n8n/chat` React Widget

If your goal is to add an AI support copilot or interactive workflow assistant to your website, n8n maintains an official web chat widget package: `@n8n/chat`.

### Integrating into Next.js App Router

Because the widget touches DOM window objects, wrap it in a client component:

```tsx
"use client";

import { useEffect } from "react";
import "@n8n/chat/style.css";

export function N8nChatWidget() {
  useEffect(() => {
    let mounted = true;

    async function loadChat() {
      const { createChat } = await import("@n8n/chat");
      if (!mounted) return;

      createChat({
        webhookUrl: "https://your-n8n-instance.com/webhook/chat-endpoint",
        target: "#n8n-chat-container",
        mode: "window",
        chatInputKey: "chatInput",
        chatSessionKey: "sessionId",
        metadata: {
          app: "my-nextjs-app",
        },
        initialMessages: [
          "Hello! How can I assist you with your project today?",
        ],
        i18n: {
          en: {
            title: "Support Assistant",
            subtitle: "Powered by n8n workflow intelligence",
            inputPlaceholder: "Type your question...",
          },
        },
      });
    }

    loadChat();

    return () => {
      mounted = false;
    };
  }, []);

  return <div id="n8n-chat-container" />;
}
```

### The CORS Configuration Everyone Forgets
By default, your self-hosted n8n instance will block requests originating from `https://yourdomain.com` with a browser CORS error.

In your n8n Docker environment, set:
```bash
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
WEBHOOK_URL=https://your-n8n-instance.com/
```
And on the Chat Webhook node itself, set **Allowed Origins** to your Next.js domain (e.g. `https://www.razi.pro`) rather than leaving it as a wildcard `*`.

---

## Level C: Custom Management Portal over n8n REST API

What if your customer needs to see their workflow execution logs, inspect generated PDF outputs, or manually trigger automations with custom parameters?

Instead of forcing users to log into n8n directly, build a custom UI in React that queries n8n's public REST API (`/api/v1`).

n8n provides a fully featured management API:
- `GET /api/v1/workflows`: List active workflows
- `POST /api/v1/workflows/{id}/activate`: Enable/disable workflows
- `GET /api/v1/executions`: Inspect execution history, duration, and error traces

### The Rule: Never put the n8n API Key in the Browser
n8n API keys hold full administrative control over your instance. **Always proxy requests through your Next.js backend:**

```typescript
// app/api/admin/executions/route.ts
import { NextResponse } from "next/server";
import { auth } from "@/lib/auth/auth";

export async function GET() {
  const session = await auth();
  if (!session?.user?.isAdmin) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  const n8nBaseUrl = process.env.N8N_BASE_URL || "http://localhost:5678";
  const apiKey = process.env.N8N_API_KEY!;

  const res = await fetch(`${n8nBaseUrl}/api/v1/executions?limit=20`, {
    headers: {
      "X-N8N-API-KEY": apiKey,
      Accept: "application/json",
    },
    // Don't cache in production so logs are fresh
    cache: "no-store",
  });

  const data = await res.json();
  return NextResponse.json(data);
}
```

Your React UI can render a clean shadcn or Tailwind table showing recent runs, status badges, and retry buttons without exposing administrative credentials.

---

## Level D: The Visual Canvas Studio (When You Actually Need It)

Level D is when you want your users to open a visual builder inside an `` or embedded canvas, drag nodes around, and connect arrows to create custom integrations inside your SaaS.

### The Reality Check
1. **The Community Edition Licence Does Not Allow Reselling n8n as a Service**:
   n8n's open-source Sustainable Use Licence allows you to run n8n for internal tools and business operations. It **does not allow** you to offer n8n's visual builder as a commercial white-labelled product to third-party users without an **n8n Embed Licence**.
2. **Multi-Tenant Isolation is Non-Trivial**:
   If user A and user B both write JavaScript Code nodes inside an embedded n8n instance, they share the execution runtime unless each customer runs in a segregated Docker container or dedicated workspace.
3. **The Embed Licence**:
   n8n offers an official **n8n Embed** programme with tenancy isolation, billing integration, and OEM embedding rights. For B2B platforms looking to add "Zapier for our customers", it is worth every penny of the commercial licence. For individual developers, **Level A or Level C is almost always what you actually wanted.**

---

## Summary & Architecture Decision Matrix

| Goal | Pick This | Key Implementation Detail |
|---|---|---|
| Trigger automations from website forms or buttons | **Level A** | Next.js server route + async Webhook node |
| Add a conversational AI assistant | **Level B** | `@n8n/chat` client component + CORS domain pin |
| Show customers their automation history | **Level C** | Next.js server proxy calling `/api/v1/executions` |
| Let customers build custom visual automations | **Level D** | Contact n8n for OEM Embed licensing |

---

### Related reading & production workflows

- [n8n: Respond to a Webhook Instantly and Keep the Workflow Running](https://www.razi.pro/blog/n8n-respond-to-webhook-without-waiting) — The decoupled response pattern that prevents Next.js gateway timeouts.
- [Building Serverless Workflows: Integrating n8n with Next.js](https://www.razi.pro/blog/n8n-nextjs-integration-guide) — Secure server-to-server webhook dispatching.
- [Automating Contact Forms with n8n and Real-Time Responses](https://www.razi.pro/blog/automated-contact-form-n8n-real-time-responses) — razi.pro's live contact pipeline.
