Reach

Multilingual Support for the Chatbot

⏱ 13 min

A visitor who types a question in Spanish deserves a real answer, not a shrug or a reply in the wrong language. There is no dedicated multilingual feature in the PHP AI Client SDK, no ->translate() method, no locale-aware retrieval mode. What there is, is wp_ai_client_prompt() itself, the same general text-generation call this entire track has used from Course 5 onward, applied to a translation task instead of an answer. This lesson builds multilingual support honestly, out of that one general capability, with no invented API pretending to be more specialized than it is.

What you'll learn in this lesson
Why there's no dedicated multilingual SDK feature
And why that's fine, translation is just another text-generation call.
Translating the visitor's question before retrieval
So semantic search runs against content in the language it was actually indexed in.
Translating the final answer back
The visitor reads their own language, the retrieval pipeline never has to.
A cheap language-detection step
Asking the model directly, since there's no dedicated detection endpoint either.
Prerequisites

Lesson 3’s my_plugin_answer_with_verified_citations(), and content indexed in a single primary language, most sites’ knowledge bases are.

Step 1: be clear about what’s actually available

This is general translation, not a WordPress multilingual feature

Nothing in wordpress/php-ai-client is built specifically for multilingual support. Everything in this lesson is wp_ai_client_prompt(), the ordinary text-generation call, asked to translate rather than answer. That’s a completely legitimate use of a general-purpose language model, but it’s worth being precise about: if a WordPress-native multilingual API ships later, this lesson’s approach still works underneath it, only the entry point might change.

Step 2: detect the visitor’s language

There’s no dedicated detection endpoint either, so ask the model directly, cheaply, with a small max token limit since the answer is only ever a short language name or code:

// File: my-plugin/class-multilingual.php
function my_plugin_detect_language( string $text ): string {
	$result = wp_ai_client_prompt( $text )
		->using_system_instruction(
			'Identify the language of the following text. Respond with only its ' .
			'ISO 639-1 code, such as "en" or "es". Nothing else.'
		)
		->using_max_tokens( 10 )
		->generate_text();

	return is_wp_error( $result ) ? 'en' : trim( strtolower( $result ) );
}

Falling back to 'en' on a WP_Error keeps the pipeline moving even if this detection step itself fails, worst case the visitor gets an English answer instead of the whole request breaking.

Step 3: translate the question into your content’s language before retrieval

Semantic search compares embeddings of the question against embeddings of your indexed chunks. If your knowledge base was indexed in English and the question arrives in Spanish, translating the question into English before embedding it gives retrieval something closer to what your stored vectors actually represent:

// File: my-plugin/class-multilingual.php
function my_plugin_translate_text( string $text, string $target_language ): string {
	$result = wp_ai_client_prompt( $text )
		->using_system_instruction(
			"Translate the following text into {$target_language}. Return only the " .
			'translation, nothing else, no explanation.'
		)
		->generate_text();

	return is_wp_error( $result ) ? $text : $result;
}
// File: my-plugin/class-multilingual.php
function my_plugin_answer_multilingual( string $question ): array {
	$visitor_language = my_plugin_detect_language( $question );

	$search_question = 'en' === $visitor_language
		? $question
		: my_plugin_translate_text( $question, 'English' );

	$result = my_plugin_answer_with_verified_citations( $search_question );

	if ( 'en' !== $visitor_language ) {
		$result['answer'] = my_plugin_translate_text( $result['answer'], $visitor_language );
	}

	return $result;
}

Retrieval, citation validation, and the grounded prompt from Lesson 3 all run entirely in English underneath this function, exactly as built. Only the question going in and the answer coming out are translated, the retrieval pipeline itself never needs to know multiple languages exist.

Two extra model calls per non-English question

Detecting the language and translating the question each cost a separate call before retrieval even runs, and translating the answer back costs one more, up to three extra calls for a non-English visitor versus zero for an English one. Cache the detected language for the session (Course 11’s transient pattern applies directly) so it’s detected once per conversation, not once per message.

Step 4: an alternative worth naming, translate content once instead

Translating every question and answer on the fly is simple but pays a latency and cost tax on every non-English message. An alternative for a site with a large, stable non-English visitor base is translating and indexing the content itself once, ahead of time, into a second set of chunks tagged by language, so retrieval runs natively in the visitor’s own language with no per-message translation call at all. That’s real additional infrastructure, effectively repeating Lesson 2’s indexing pass once per target language, and only worth building once you’ve confirmed sustained demand in a specific language, not speculatively for every language your visitors might theoretically use.

Test it: ask the same question in two languages

wp-env run cli wp eval '
$r1 = my_plugin_answer_multilingual( "How do I request a refund?" );
echo "EN: " . $r1["answer"] . "\n\n";

$r2 = my_plugin_answer_multilingual( "¿Cómo solicito un reembolso?" );
echo "ES: " . $r2["answer"] . "\n";
'

Both answers should reflect the same underlying refund policy content, and the second should read as natural Spanish, not a stiff, literal translation. If citations differ wildly between the two, retrieval likely picked up a bad translation on the way in, check Step 3’s search_question before assuming the knowledge base itself is at fault.

Recap

There’s no dedicated multilingual feature to reach for, and pretending otherwise would be dishonest about what the SDK actually offers. wp_ai_client_prompt(), the same general call this entire track has used, handles detection and translation as ordinary text-generation tasks: detect the visitor’s language, translate the question into your content’s language before retrieval runs, translate the final answer back. Everything built in Lessons 1 through 4 keeps working underneath this, entirely unaware that multiple languages exist at all.

Resources & further reading

← Building the Live Chat Takeover Adding Voice Input →