Skip to main content
RapidDev - Software Development Agency
n8n-tutorial

How to Handle Multi-Language Inputs Correctly in Claude Workflows with n8n

Non-English text sent to Claude via n8n can break due to encoding issues, truncated characters, or incorrect content-type headers. Fix this by enforcing UTF-8 encoding in HTTP Request nodes, normalizing Unicode before passing text to the Anthropic node, and setting explicit character encoding in webhook responses so multi-language inputs arrive intact.

What you'll learn

  • How to configure webhook nodes to preserve UTF-8 encoding for non-English input
  • How to normalize Unicode text in the Code node before sending to Claude
  • How to set correct content-type headers with charset in HTTP Request nodes
  • How to validate round-trip encoding so responses display correctly
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Advanced8 min read25-35 minutesn8n 1.30+, Anthropic Claude 3/3.5 models, HTTP Request node v4+March 2026RapidDev Engineering Team
TL;DR

Non-English text sent to Claude via n8n can break due to encoding issues, truncated characters, or incorrect content-type headers. Fix this by enforcing UTF-8 encoding in HTTP Request nodes, normalizing Unicode before passing text to the Anthropic node, and setting explicit character encoding in webhook responses so multi-language inputs arrive intact.

Why Multi-Language Inputs Break in Claude Workflows

When users send text in languages like Chinese, Arabic, Japanese, or Korean through an n8n workflow to Claude, several things can go wrong. Webhook nodes may not preserve UTF-8 encoding, expression interpolation can mangle multi-byte characters, and JSON serialization in the HTTP Request node may escape Unicode unnecessarily. Claude itself handles multilingual text perfectly — the problem is almost always in how n8n passes the text to the API. This tutorial walks through every encoding pitfall and shows you how to build a bullet-proof multilingual Claude pipeline.

Prerequisites

  • A running n8n instance (self-hosted or cloud) on version 1.30 or later
  • An Anthropic API credential configured in n8n
  • Basic understanding of n8n expressions and the Code node
  • A workflow that accepts user input via Webhook or Chat Trigger
  • Familiarity with UTF-8 encoding concepts

Step-by-step guide

1

Configure the Webhook node to accept UTF-8 input

Open your Webhook node and ensure the response content-type is set to application/json with an explicit charset. By default, n8n webhooks accept UTF-8, but downstream nodes may misinterpret the encoding if the header is ambiguous. In the Webhook node settings, set Response Content-Type to 'application/json; charset=utf-8'. Also set the HTTP Method to POST so the body is parsed as JSON rather than URL-encoded, which can mangle multi-byte characters.

Expected result: Webhook accepts POST requests and correctly parses JSON bodies containing non-English characters without mojibake.

2

Normalize Unicode in a Code node

Different systems may send the same character in different Unicode forms (NFC vs NFD). For example, an accented 'é' can be one codepoint or two. Claude handles both, but downstream string operations in n8n (like truncation or length checks) can split multi-byte sequences if the form is inconsistent. Add a Code node right after your Webhook to normalize all text input to NFC form. This ensures consistent character counting and prevents truncation bugs when you later check token limits.

typescript
1// Code node — JavaScript
2const items = $input.all();
3
4for (const item of items) {
5 const userText = item.json.message || item.json.text || '';
6 // Normalize to NFC (composed form)
7 item.json.normalizedText = userText.normalize('NFC');
8 // Accurate character count for multi-byte text
9 item.json.charCount = [...item.json.normalizedText].length;
10}
11
12return items;

Expected result: The normalizedText field contains NFC-normalized text and charCount reflects the true character count, not byte count.

3

Pass normalized text to the Anthropic Claude node

In your Anthropic node (or AI Agent node with Claude as the model), reference the normalizedText field from the previous Code node. Use the expression {{ $json.normalizedText }} in the user message field. Do not use string concatenation with + in expressions for multi-language text — always use template literals or direct field references. String concatenation in n8n expressions can sometimes trigger implicit toString() calls that re-encode characters.

Expected result: Claude receives the full, unmangled multi-language text and responds appropriately in the same language or as instructed.

4

Set explicit encoding on HTTP Request nodes for custom API calls

If you are calling the Anthropic API directly via an HTTP Request node instead of the built-in Anthropic node, you must set the Content-Type header to 'application/json; charset=utf-8' explicitly. In the HTTP Request node, go to Options → Headers and add this header. Also ensure the body is sent as JSON (not raw text), because raw text mode may apply platform-default encoding which varies between Linux and Windows n8n installations.

typescript
1// HTTP Request node configuration (set in node UI):
2// Method: POST
3// URL: https://api.anthropic.com/v1/messages
4// Headers:
5// Content-Type: application/json; charset=utf-8
6// x-api-key: {{ $credentials.anthropicApi.apiKey }}
7// anthropic-version: 2023-06-01
8// Body (JSON):
9{
10 "model": "claude-3-5-sonnet-20241022",
11 "max_tokens": 1024,
12 "messages": [
13 {
14 "role": "user",
15 "content": "{{ $json.normalizedText }}"
16 }
17 ]
18}

Expected result: The HTTP Request node sends properly encoded JSON to the Anthropic API and receives a valid response with multi-language text intact.

5

Validate round-trip encoding in the response

Add a second Code node after the Claude response to verify that the response text is valid UTF-8 and contains the expected characters. This is especially important for CJK (Chinese, Japanese, Korean) text and RTL (right-to-left) languages like Arabic and Hebrew. Log any encoding anomalies so you can catch issues before they reach the end user. This validation step also protects against rare cases where the API response is double-encoded.

typescript
1// Code node — JavaScript
2const items = $input.all();
3
4for (const item of items) {
5 const responseText = item.json.message?.content?.[0]?.text
6 || item.json.output
7 || '';
8
9 // Check for common encoding corruption patterns
10 const hasMojibake = /Ã[\x80-\xBF]/.test(responseText);
11 const hasReplacementChar = responseText.includes('\uFFFD');
12
13 item.json.responseText = responseText;
14 item.json.encodingValid = !hasMojibake && !hasReplacementChar;
15
16 if (!item.json.encodingValid) {
17 item.json.encodingWarning = 'Response contains encoding artifacts — check upstream headers';
18 }
19}
20
21return items;

Expected result: encodingValid is true and responseText displays correctly in all languages. If false, the encodingWarning field provides a debugging hint.

6

Return the response with correct encoding headers

If your workflow responds via the Webhook node (Respond to Webhook), ensure the response also uses UTF-8. In the Respond to Webhook node, set the Response Content-Type to 'application/json; charset=utf-8'. If you are returning HTML (for a chat widget), use 'text/html; charset=utf-8'. Without this, browsers may render the response in ISO-8859-1, turning CJK and accented characters into garbage. This closes the encoding loop end-to-end.

Expected result: The webhook response displays multi-language text correctly in the browser, Postman, or any client consuming the API.

Complete working example

normalize-and-validate-encoding.js
1// Complete Code node: normalize input + validate output
2// Place this as a Function node after your Webhook and before Claude
3
4const items = $input.all();
5const results = [];
6
7for (const item of items) {
8 const raw = item.json.message || item.json.text || item.json.body || '';
9
10 // Step 1: Normalize to NFC
11 const normalized = raw.normalize('NFC');
12
13 // Step 2: Count true characters (not bytes)
14 const charCount = [...normalized].length;
15 const byteCount = new TextEncoder().encode(normalized).length;
16
17 // Step 3: Detect encoding issues in input
18 const hasMojibake = /Ã[\x80-\xBF]/.test(normalized);
19 const hasNullBytes = normalized.includes('\x00');
20 const hasReplacementChar = normalized.includes('\uFFFD');
21
22 // Step 4: Detect language/script
23 const isCJK = /[\u4E00-\u9FFF\u3040-\u309F\u30A0-\u30FF\uAC00-\uD7AF]/.test(normalized);
24 const isRTL = /[\u0600-\u06FF\u0590-\u05FF]/.test(normalized);
25 const isCyrillic = /[\u0400-\u04FF]/.test(normalized);
26
27 // Step 5: Build clean output
28 results.push({
29 json: {
30 normalizedText: normalized,
31 charCount,
32 byteCount,
33 multiByte: byteCount > charCount,
34 detectedScript: isCJK ? 'CJK' : isRTL ? 'RTL' : isCyrillic ? 'Cyrillic' : 'Latin',
35 encodingClean: !hasMojibake && !hasNullBytes && !hasReplacementChar,
36 warnings: [
37 hasMojibake ? 'Mojibake detected — input was likely double-encoded' : null,
38 hasNullBytes ? 'Null bytes found — strip before sending to Claude' : null,
39 hasReplacementChar ? 'Replacement characters found — source encoding is not UTF-8' : null
40 ].filter(Boolean)
41 }
42 });
43}
44
45return results;

Common mistakes when handling Multi-Language Inputs Correctly in Claude Workflows with n8n

Why it's a problem: Using str.length to check if input is within token limits — this counts UTF-16 code units, not characters

How to avoid: Use [...str].length or Array.from(str).length for an accurate character count

Why it's a problem: Sending multi-language text as URL query parameters instead of POST body

How to avoid: Always use POST with a JSON body for non-ASCII text — URL encoding mangles multi-byte characters

Why it's a problem: Concatenating user input with + operator in n8n expressions which can trigger implicit encoding

How to avoid: Use template literals or direct field references: {{ $json.normalizedText }}

Why it's a problem: Not setting charset on the Respond to Webhook node, causing browsers to render garbage

How to avoid: Set Response Content-Type to 'application/json; charset=utf-8' in the Respond to Webhook node

Why it's a problem: Assuming Claude's response will be in the same language as the input without instructing it

How to avoid: Add a system message: 'Respond in the same language the user writes in unless asked otherwise'

Best practices

  • Always set Content-Type: application/json; charset=utf-8 on both request and response headers
  • Normalize all user input to Unicode NFC form before any string operations
  • Use spread syntax [...str].length for character counting instead of str.length which counts UTF-16 code units
  • Never truncate multi-byte strings with .substring() — use Array.from(str).slice() instead
  • Test with at least three scripts: Latin with accents, CJK, and RTL (Arabic or Hebrew)
  • Log byte count vs character count to catch double-encoding issues early
  • Use the built-in Anthropic node when possible — it handles encoding correctly by default
  • Pin test data with multi-language text so you can re-run without retyping

Still stuck?

Copy one of these prompts to get a personalized, step-by-step explanation.

ChatGPT Prompt

I'm building an n8n workflow that sends multi-language user input (Chinese, Arabic, Japanese) to Claude via the Anthropic node. The characters arrive garbled. How do I fix encoding issues end-to-end, from Webhook input to Claude response to Webhook output?

n8n Prompt

My n8n Webhook receives Japanese text but by the time it reaches the Claude node the characters are corrupted. How do I normalize Unicode and set correct charset headers in the workflow?

Frequently asked questions

Does the built-in n8n Anthropic node handle UTF-8 encoding automatically?

Yes, the built-in Anthropic node sends and receives UTF-8 by default. Encoding issues typically arise upstream — in Webhook nodes, Code nodes, or HTTP Request nodes that feed into the Anthropic node.

Why does my Japanese text display correctly in the n8n editor but arrive garbled at Claude?

The n8n editor renders text in UTF-8, but the expression evaluation engine may re-encode text during interpolation. Use direct field references ({{ $json.field }}) instead of string concatenation to preserve encoding.

Can I use the Chat Trigger node for multi-language chatbots?

Yes, the Chat Trigger node handles UTF-8 encoding correctly for its built-in chat widget. If you are using a custom frontend, ensure your frontend sends the correct Content-Type header with charset=utf-8.

How do I handle mixed-language input where users write in both English and Chinese in the same message?

NFC normalization handles mixed-language text correctly. The key is to never truncate the string mid-character — use Array.from() for any slicing operations.

Do I need to set encoding differently for Claude 3 vs Claude 3.5 models?

No, all Claude models accept UTF-8 input identically. The encoding configuration is about how n8n transmits the text, not about the model's capabilities.

What is RapidDev and can they help with complex multi-language n8n workflows?

RapidDev is a development service that specializes in building production-grade n8n workflows. For complex internationalization requirements — like multi-language chatbots with memory, region-specific routing, or CJK text processing pipelines — their engineering team can help architect and implement the solution.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.