// Decide when to use n8n workflows versus Next.js server actions for backend logic. Use when implementing complex multi-step workflows, AI agent pipelines, or external service integrations. Provides patterns for both runtime webhook integration and development-time architectural decisions.
| name | n8n-integration-patterns |
| description | Decide when to use n8n workflows versus Next.js server actions for backend logic. Use when implementing complex multi-step workflows, AI agent pipelines, or external service integrations. Provides patterns for both runtime webhook integration and development-time architectural decisions. |
Guide for deciding between n8n workflow automation and Next.js server actions when implementing backend features.
This skill helps you make architectural decisions about where to implement backend logic:
The organization maintains an n8n instance at https://n8n.reodorstudios.com with comprehensive MCP integration for workflow development.
โ CRUD Operations - Standard database create, read, update, delete โ Simple Business Logic - Authentication, authorization, data validation โ Direct Database Queries - Supabase client operations with RLS โ Form Submissions - User input processing with Zod validation โ API Integrations (Simple) - Single API call with straightforward response handling โ Type Safety Required - End-to-end TypeScript type checking needed โ Fast Response Times - Operations that must complete in <5 seconds
Rationale: Server actions provide excellent DX, full type safety from database โ frontend, and tight integration with React components.
โ Complex Multi-Step Workflows - 5+ steps with branching logic and error handling โ AI Agent Pipelines - Multiple AI interactions with tool usage and decision trees โ External Service Orchestration - Coordinating 3+ external APIs (Notion โ AI โ Slack โ Database) โ Long-Running Tasks - Operations taking >10 seconds (batch processing, data transformations) โ Scheduled Automation - Cron-based tasks with complex schedules and dependencies โ Webhook Chaining - Receiving webhooks that trigger multi-step processes โ Visual Workflow Design - Non-developers need to understand/modify the logic โ Rapid Prototyping - Testing complex integrations without writing code
Rationale: n8n excels at orchestrating complex, multi-step processes with visual debugging, pre-built integrations, and easy modifications.
Use Server Actions โ
// server/profile.actions.ts
"use server";
export async function updateProfile(data: ProfileUpdate) {
const supabase = await createClient();
const {
data: { user },
} = await supabase.auth.getUser();
return await supabase.from("profiles").update(data).eq("id", user.id);
}
Why: Simple CRUD, requires RLS, needs type safety, fast response.
Use n8n Workflow โ
Webhook Trigger
โ Fetch content from Notion (n8n Notion node)
โ AI Agent: Summarize content (OpenAI node)
โ AI Agent: Generate social posts (OpenAI node)
โ Store in database (Supabase node)
โ Post to Slack (Slack node)
โ Send confirmation email (Resend node)
โ Respond to webhook
Why: 6+ steps, multiple external services, AI interactions, long-running, benefits from visual debugging.
Use Server Actions โ
// server/ai.actions.ts
"use server";
export async function generateSummary(text: string) {
const response = await openai.chat.completions.create({
model: "gpt-4",
messages: [{ role: "user", content: `Summarize: ${text}` }],
});
return response.choices[0].message.content;
}
Why: Single AI call, needs type safety, integrated with React components, fast response.
Use n8n Workflow โ
Webhook: New Booking Request
โ Validate booking data
โ Check calendar availability (external API)
โ If available:
โ Create booking in database
โ Send confirmation email
โ Create calendar event
โ Notify admin on Slack
โ Trigger payment processing
โ If not available:
โ Find alternative slots (AI agent)
โ Send suggestions email
โ Respond to webhook
Why: Complex branching logic, multiple external services, error handling at each step, benefits from visual flow.
Call n8n workflows from server actions when needed:
// server/workflow.actions.ts
"use server";
import { env } from "@/lib/env";
interface N8nWebhookResponse {
status: string;
data?: any;
error?: string;
}
export async function triggerN8nWorkflow<T = any>(
workflowPath: string,
data: any
): Promise<N8nWebhookResponse> {
try {
const response = await fetch(`${env.N8N_WEBHOOK_URL}/${workflowPath}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${env.N8N_WEBHOOK_SECRET}`,
},
body: JSON.stringify(data),
});
if (!response.ok) {
return {
status: "error",
error: `Workflow failed: ${response.statusText}`,
};
}
const result = await response.json();
return { status: "success", data: result };
} catch (error) {
console.error("n8n workflow error:", error);
return {
status: "error",
error: error instanceof Error ? error.message : "Unknown error",
};
}
}
// Usage example
export async function processComplexOrder(orderId: string) {
const supabase = await createClient();
// Get order data from database
const { data: order } = await supabase
.from("orders")
.select("*")
.eq("id", orderId)
.single();
// Trigger n8n workflow for complex processing
const result = await triggerN8nWorkflow("process-order", {
orderId,
orderData: order,
});
if (result.status === "error") {
return { error: result.error, data: null };
}
return { error: null, data: result.data };
}
Add n8n configuration to your environment variables:
// lib/env.ts
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";
export const env = createEnv({
server: {
// ... existing env vars
N8N_WEBHOOK_URL: z.string().url().optional(),
N8N_WEBHOOK_SECRET: z.string().optional(),
},
});
# .env.local
N8N_WEBHOOK_URL=https://n8n.reodorstudios.com/webhook
N8N_WEBHOOK_SECRET=your-webhook-secret
During feature planning, consider both approaches:
// Option A: Server Action (Simple AI query)
export async function generateBlogPost(topic: string) {
const content = await openai.generate({ topic });
const supabase = await createClient();
return await supabase.from("posts").insert({ content });
}
// Option B: n8n Workflow (Complex content pipeline)
// When the flow involves:
// - Multiple AI generations (outline โ content โ social posts)
// - External research (web scraping, API calls)
// - Multi-platform publishing (blog, social, newsletter)
// - Content approval workflow
// โ Build workflow in n8n repo instead
The organization maintains a separate n8n repository with comprehensive tooling:
/path/to/your/repo/reodor-studios/n8n/
When developing n8n workflows, you have access to:
search_nodes - Find n8n nodes by functionalityget_node_info - Detailed node documentationget_node_essentials - Minimal config for operationssearch_templates - Find workflow examplesvalidate_workflow - Check workflow before deploymentcreate_workflow - Deploy to n8n instanceThe n8n repo includes 7 specialized skills:
Server Actions โ for subscriber management:
// server/newsletter.actions.ts
export async function subscribeToNewsletter(email: string) {
const supabase = await createClient();
return await supabase.from("subscribers").insert({ email });
}
n8n Workflow โ for sending newsletters:
Cron Trigger (Weekly)
โ Fetch new blog posts (Supabase)
โ Generate newsletter content (AI)
โ Fetch subscribers (Supabase)
โ Send emails (Resend batch)
โ Track opens/clicks
โ Update analytics (Supabase)
Server Actions โ for initial signup:
export async function createUser(data: SignupData) {
const supabase = await createClient();
const { data: user } = await supabase.auth.signUp(data);
await supabase.from("profiles").insert({ user_id: user.id });
return user;
}
n8n Workflow โ for onboarding email sequence:
Webhook: New User Created
โ Wait 1 hour
โ Send welcome email
โ Wait 24 hours
โ Send feature guide email
โ Wait 3 days
โ Check if user is active
โ If inactive: Send re-engagement email
โ If active: Send pro tips email
// Standard approach using Supabase client
const { data, error } = await myServerAction(params);
if (error) {
toast.error(error.message);
return;
}
// Process data
# Test n8n webhook locally
curl -X POST \
https://n8n.reodorstudios.com/webhook/test-workflow \
-H "Content-Type: application/json" \
-d '{"test": "data"}'
Consider migration when:
Consider migration when:
โ Default to server actions for standard features โ Use n8n for complex, multi-step orchestration โ Document workflow purpose in both code and n8n โ Secure n8n webhooks with authentication โ Version control n8n workflow JSON files โ Test workflows thoroughly before production โ Monitor n8n execution logs for errors
โ Use n8n for simple CRUD operations โ Skip type validation when calling n8n webhooks โ Hardcode secrets in workflow configurations โ Deploy untested workflows to production โ Build complex AI agents in server actions (use n8n) โ Ignore n8n execution failures silently
Default Choice: Next.js Server Actions for standard features
Consider n8n When:
Integration: Call n8n webhooks from server actions when needed
Development: Use n8n repo with MCP tools and specialized skills
For detailed n8n workflow development, see:
/Users/magnusrodseth/dev/capra/reodor-studios/n8n/docs/technical/n8n-integration.md (to be created)https://n8n.reodorstudios.com