Over 43% of all websites run on WordPress, yet most creators still manually copy-paste content from Google Docs, Notion, or Airtable into the block editor — wasting 5+ hours weekly on repetitive formatting, image uploads, and SEO meta entry. n8n, the source-available workflow automation platform founded in Berlin in 2019 and now valued at $2.5B after a $180M Series C in October 2025, lets you build a custom publishing pipeline that moves content from draft to live post with zero code and zero monthly SaaS fees when self-hosted. This guide shows exactly how to connect your content source, transform data via n8n's visual node editor, and push polished posts to WordPress via its REST API — all on a $5/month VPS or free tier — so you publish 10x faster without sacrificing control or SEO.
Quick Answer: Self-host n8n on a $5/month VPS, create a workflow that triggers on new rows in Google Sheets or Airtable, use HTTP Request nodes to call WordPress REST API endpoints (/wp/v2/posts, /wp/v2/media) with Application Passwords auth, map fields (title, content, categories, tags, featured image), add error handling and conditional logic for draft vs publish, then schedule or webhook-trigger the workflow for fully automated publishing at near-zero cost.
Why Automate WordPress Publishing with n8n
Eliminate Manual Bottlenecks at Scale
Manual publishing creates invisible friction: formatting inconsistencies, missed alt tags, forgotten categories, and delayed schedules. A 2024 Content Marketing Institute survey found teams spend 37% of content time on production tasks rather than strategy. n8n's node-based editor — used by 16,000+ community members as of April 2021 — replaces 20+ click sequences with a single automated workflow that runs on your infrastructure.
Own Your Data and Avoid Vendor Lock-In
Unlike Zapier ($29.99/mo for 750 tasks) or Make ($9/mo for 10k operations), n8n's self-hosted edition imposes no execution limits, task caps, or data egress fees. Your content never leaves your server. The platform's source-available license (Sustainable Use License v1.1) permits commercial self-hosting indefinitely, a critical advantage for GDPR-sensitive publishers and budget-constrained teams.
Real Example: Niche Affiliate Site Scales to 200 Posts/Month
A travel affiliate publisher migrated from manual WordPress entry to an n8n workflow pulling from Airtable. The workflow: (1) triggers on "Ready to Publish" view change, (2) downloads featured image from Cloudinary URL, (3) uploads to WordPress media library via REST API, (4) creates post with Yoast SEO fields mapped from Airtable columns, (5) assigns categories/tags via taxonomy endpoints, (6) returns post URL to Airtable. Result: 14 hours/week saved, zero formatting errors, $4.50/month VPS cost vs $299/month Zapier Team plan.
Prerequisites: What You Need Before Starting
Infrastructure: Cheap VPS or Local Docker
Provision a $5/month VPS (1 vCPU, 1 GB RAM, 25 GB SSD) from DigitalOcean, Linode, or Hetzner. Install Docker and Docker Compose — n8n's official Docker image runs on Node.js 20+ and requires ~512 MB RAM idle. For zero-cost testing, run locally via `docker run -it --rm --name n8n -p 5678:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n`.
WordPress: Enable REST API and Application Passwords
WordPress 5.6+ (released December 2020) includes Application Passwords natively. Go to Users → Profile → Application Passwords, name it "n8n-automation", copy the generated 24-character password (shown once). No plugins needed. Verify REST API works: `curl -u "username:app_password" https://yoursite.com/wp-json/wp/v2/posts`.
Content Source: Structured Data in Google Sheets, Airtable, or Notion
Your content must live in a queryable table with columns: title, content (HTML or markdown), status (draft/publish), categories (comma-separated slugs), tags, featured_image_url, seo_title, meta_description. n8n natively supports Google Sheets (OAuth2), Airtable (personal access token), and Notion (internal integration token) via dedicated nodes.
Step-by-Step: Build Your First Publishing Workflow
1. Install and Secure n8n on Your VPS
- SSH into VPS, create docker-compose.yml with n8n service, PostgreSQL (recommended for production), and Caddy for automatic HTTPS via Let's Encrypt.
- Set environment variables: `N8N_BASIC_AUTH_ACTIVE=true`, `N8N_BASIC_AUTH_USER=admin`, `N8N_BASIC_AUTH_PASSWORD=strongpassword`, `N8N_HOST=automation.yourdomain.com`, `N8N_PROTOCOL=https`, `WEBHOOK_URL=https://automation.yourdomain.com/`.
- Run `docker compose up -d`. Access https://automation.yourdomain.com, complete setup wizard.
2. Create Workflow: Trigger on New Content
- Click "New Workflow". Add "Google Sheets Trigger" node (or Airtable/Notion equivalent). Configure: Spreadsheet ID, Sheet Name, Polling Interval (5 min), Trigger Column (e.g., "Status" = "Ready").
- Test: Add a row with Status "Ready" → workflow executes → check "Executions" tab for payload.
3. Transform and Validate Data with Function/Set Nodes
- Add "Set" node to map Google Sheets columns to WordPress fields: `title`, `content` (run through Markdown-to-HTML function if needed), `status` (draft/publish), `categories` (array of term IDs — use separate HTTP Request to `/wp/v2/categories?search=slug` to resolve), `tags`, `meta` (Yoast/RankMath fields).
- Add "IF" node: if featured_image_url exists → continue to image upload; else skip to post creation.
4. Upload Featured Image via WordPress Media Endpoint
- Add "HTTP Request" node: Method POST, URL `https://yoursite.com/wp-json/wp/v2/media`, Authentication: Header Auth (Authorization: Basic base64(username:app_password)).
- Headers: `Content-Type: image/jpeg` (or png/webp), `Content-Disposition: attachment; filename="image.jpg"`.
- Binary Data: Enable "Binary Data" toggle, set Property Name to `file`, Input Binary Field to `data` (from previous "HTTP Request" node that downloads image from Cloudinary/CDN URL).
- Response: Capture `id` (media ID) → pass to post creation node via `featured_media` field.
5. Create or Update Post via WordPress Posts Endpoint
- Add "HTTP Request" node: Method POST (create) or PUT (update if post_id exists), URL `https://yoursite.com/wp-json/wp/v2/posts` (or `/wp/v2/posts/{{$json.post_id}}`).
- JSON Body: Include all mapped fields. For categories/tags, send arrays of term IDs: `categories: [12, 34]`, `tags: [5, 8]`.
- Authentication: Same Header Auth as media upload.
- On success, capture `id`, `link`, `date` → write back to Google Sheets via "Google Sheets" node (Update Row) for audit trail.
6. Error Handling, Retry Logic, and Notifications
- Enable "Continue On Fail" on HTTP Request nodes. Add "Error Trigger" workflow (separate workflow) that receives error payload via n8n's built-in error webhook.
- In Error Trigger workflow: Send Slack/Email/Telegram alert with execution URL, failed node name, and error message. Add 3-retry loop with exponential backoff (Wait node: 30s, 60s, 120s) before final alert.
Advanced Patterns: Scale Beyond Basic Publishing
Conditional Publishing: Draft vs Live vs Scheduled
Use a "Switch" node on `status` field: "draft" → POST to `/wp/v2/posts` with `status: draft`; "publish" → `status: publish`; "future" → `status: future` + `date: 2025-01-15T09:00:00`. This single workflow handles editorial calendars without manual scheduling.
Bulk Import from CSV/Export with Pagination
For migrating 500+ posts, add "Read Binary File" node (CSV) → "Split In Batches" node (batch size 10) → loop through same HTTP Request nodes. Respect WordPress rate limits: add "Wait" node (1s) between batches. Use `per_page=100` and `page` parameters for exporting existing posts via GET `/wp/v2/posts`.
AI-Enhanced Content: Auto-Generate SEO Meta, Excerpts, Alt Text
Insert "OpenAI" or "Ollama" (local LLM) node before post creation. Prompt: "Write 160-char meta description for: {{ $json.title }}. Content: {{ $json.content.substring(0, 2000) }}". Map output to `meta_description` and `excerpt`. For images, use "Cloud Vision" or "Ollama LLaVA" to generate alt text from image binary, then update media via PUT `/wp/v2/media/{id}` with `alt_text`.
Cost Comparison: n8n vs Zapier vs Make vs Custom Code
Below are real 2025 pricing for a workflow publishing 500 posts/month with 2 featured images each (1,500 API calls/month). All figures exclude VPS/domain costs.
Assumptions: Self-hosted n8n on $5/mo VPS; Zapier Team plan required for 1,500 tasks; Make Core plan for 10k operations; Custom Python script on same VPS.
| Platform | Monthly Cost | Yearly Cost | Task/Execution Limit | Data Ownership | Custom Logic |
|---|---|---|---|---|---|
| n8n (self-hosted) | $5 (VPS only) | $60 | Unlimited | Full — your server | JS/Python nodes, full control |
| Zapier Team | $299 | $3,588 | 2,000 tasks/mo | Zapier cloud | Limited (Code step, no loops) |
| Make Core | $29 | $348 | 10,000 ops/mo | Make cloud | Good (iterators, routers) |
| Custom Python + Cron | $5 (VPS only) | $60 | Unlimited | Full | Maximum — but build/maintain yourself |
| n8n Cloud (Starter) | $20 | $240 | 2,500 executions | n8n GmbH (EU) | Same as self-hosted |
Common Mistakes and How to Fix Them
Mistake 1: Hardcoding Credentials in Workflow Nodes
Why It Hurts: Exposes passwords in execution logs, Git exports, and shared workflows. Violates least-privilege principle.
Fix: Use n8n's built-in Credentials system (click "Credentials" → "New Credential" → "Header Auth" or "OAuth2"). Reference by name in nodes. Rotate Application Passwords quarterly.
Mistake 2: Ignoring WordPress Rate Limits and Batch Sizes
Why It Hurts: Default REST API allows ~100 requests/minute per IP. Bulk imports without throttling return 429 errors, leaving posts in limbo.
Fix: Add "Wait" node (1000ms) after each HTTP Request in loops. For high volume, implement token bucket in Function node or use WordPress `rest_api_default_filters` filter to raise limit via plugin.
Mistake 3: Mapping Category Names Instead of Term IDs
Why It Hurts: WordPress REST API requires numeric term IDs for categories/tags. Sending names creates new terms (duplicate taxonomies) or fails silently.
Fix: Pre-fetch taxonomy map: HTTP Request GET `/wp/v2/categories?per_page=100` → Function node builds `{ "travel": 12, "food": 34 }` object → Set node uses `$json.categoryMap[$json.categorySlug]`.
Mistake 4: No Idempotency — Duplicate Posts on Re-run
Why It Hurts: Re-triggering workflow (manual retry, webhook double-fire) creates identical posts. Cleanup is manual.
Fix: Store `post_id` in source row after first create. In workflow, check if `post_id` exists → use PUT `/wp/v2/posts/{id}` (update) instead of POST. Add unique constraint on source table (e.g., content_hash column).
Pro Tips
- Use n8n's "Pin Data" feature on trigger node during development — freeze a sample row to iterate without re-polling sheets.
- Enable "Save Manual Executions" and "Save Execution Progress" in n8n settings — debug failed runs with full payload inspection.
- Create a shared "WordPress API" credential set with base URL variable — switch staging/production by changing one variable.
- Log every publish to a dedicated "Audit" Google Sheet: timestamp, post_id, title, status, workflow_execution_url — essential for client reporting.
- Schedule weekly "Health Check" workflow: GET `/wp/v2/posts?per_page=1&status=publish` → verify 200 OK → alert if latency > 2s or non-2xx.
FAQ
What is n8n and how does it differ from Zapier?
n8n is a source-available workflow automation platform founded in 2019 that runs on Node.js. Unlike Zapier's closed SaaS model, n8n can be self-hosted on your own infrastructure with no execution limits, task caps, or data egress fees. It uses a visual node-based editor supporting 350+ integrations and custom JavaScript/Python code nodes.
Can I use n8n with WordPress.com or only self-hosted WordPress.org?
WordPress.com Business plan and above ($25/mo+) enable REST API and Application Passwords, so n8n works. However, WordPress.com Free/Personal/Premium plans block REST API write access. Self-hosted WordPress.org (any hosting) has full REST API support since version 4.7 (December 2016).
How do I authenticate n8n with WordPress without a plugin?
Use WordPress 5.6+ built-in Application Passwords: Users → Profile → Application Passwords → "Add New". Copy the 24-char password. In n8n, create "Header Auth" credential: Name "WP Auth", Value `Basic base64(username:app_password)`. Apply to all WordPress HTTP Request nodes.
My workflow fails with 401 Unauthorized — what's wrong?
Three common causes: (1) Application Password copied with trailing space — regenerate and copy exactly. (2) User lacks `edit_posts` capability — ensure role is Author, Editor, or Administrator. (3) Server blocks Authorization header — add `SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1` to .htaccess or nginx config.
Will n8n automation break when WordPress updates core or plugins?
WordPress REST API maintains backward compatibility — endpoints like `/wp/v2/posts` are stable since 2016. Plugin-specific fields (Yoast, ACF) may change if plugin updates modify REST schema. Mitigate: pin plugin versions, test in staging after updates, use n8n's "Continue On Fail" + error alerts to catch regressions immediately.
Conclusion
Automating WordPress publishing with n8n on a budget transforms content operations from a manual bottleneck into a reliable, scalable pipeline. By self-hosting on a $5/month VPS, you eliminate per-task fees, retain full data sovereignty, and gain unlimited custom logic via JavaScript/Python nodes — capabilities that cost $300+/month on Zapier or require weeks of custom development. The workflow pattern — trigger → transform → media upload → post create/update → audit log — handles everything from single-author blogs to 500-post/month affiliate networks. Start with the basic 6-step workflow above, then layer on conditional scheduling, AI-enhanced SEO, and bulk import as volume grows. Your future self will thank you for every hour reclaimed from copy-paste drudgery.
- Self-hosted n8n on $5 VPS = unlimited executions, zero SaaS fees, full data control
- WordPress REST API + Application Passwords = native auth, no plugins required
- Map category/tag slugs to term IDs before POST — prevents taxonomy duplicates
- Build idempotency via stored post_id — enables safe re-runs and updates
0 comments:
Post a Comment