How can I send messages from JavaScript to C# and vice versa?

Sending messages from JavaScript to C#

3D WebView has a built-in window.vuplex.postMessage() JavaScript API that you can use to send messages from JavaScript to C#. Since it's built into the browser, you don't need to include any 3rd party scripts in the page in order to utilize it. The following example illustrates how to use this JavaScript API in a page script or in a script executed via IWebView.ExecuteJavaScript():

// The window.vuplex object gets created when the page starts loading,
// so we double-check that it exists before using it here.
// You can skip this step if you're sending a message after the page has loaded.
if (window.vuplex) {
  // The window.vuplex object already exists, so go ahead and send the message.
  sendMessageToCSharp();
} else {
  // The window.vuplex object hasn't been initialized yet because the page is still
  // loading, so add an event listener to send the message once it's initialized.
  window.addEventListener('vuplexready', sendMessageToCSharp);
}

function sendMessageToCSharp() {
  // This object passed to postMessage() automatically gets serialized as JSON
  // and is emitted via the C# MessageEmitted event. This API mimics the window.postMessage API.
  window.vuplex.postMessage({ type: 'greeting', message: 'Hello from JavaScript!' });
}

The following C# demonstrates how to receive that message in Unity using the IWebView.MessageEmitted event:

void Start() {
  // This assumes that there's a WebViewPrefab already in the scene.
  var webViewPrefab = GamObject.Find("WebViewPrefab").GetComponent<WebViewPrefab>();
  webViewPrefab.Initialized += (sender, e) => {
    webViewPrefab.WebView.MessageEmitted += WebView_MessageEmitted;
  };
}

void WebView_MessageEmitted(object sender, EventArgs<string> eventArgs) {
  var json = eventArgs.Value;
  // > JSON received: { "type": "greeting", "message": "Hello from JavaScript!" }
  Debug.Log("JSON received: " + json);
}

Sending messages from C# to JavaScript

The process for sending messages from C# to JavaScript is very similar. Here's a C# script that uses IWebView.PostMessage() to send a message to JavaScript:

WebViewPrefab _webViewPrefab;

void Start() {
  _webViewPrefab = GamObject.Find("WebViewPrefab").GetComponent<WebViewPrefab>();
  _webViewPrefab.Initialized += (sender, e) => {
    // Use the LoadProgressChanged event to determine when the page has loaded.
    _webViewPrefab.WebView.LoadProgressChanged += WebView_LoadProgressChanged;
  };
}

void WebView_LoadProgressChanged(object sender, ProgressChangedEventArgs eventArgs) {
  // Send a message after the page has loaded.
  if (eventArgs.Type == ProgressChangeType.Finished) {
    _webViewPrefab.WebView.PostMessage("{\"type\": \"greeting\", \"message\": \"Hello from C#!\"}");
  }
}

And here's some JavaScript that listens for a message through the window.vuplex object's message event:

if (window.vuplex) {
  addMessageListener();
} else {
  window.addEventListener('vuplexready', addMessageListener);
}

function addMessageListener() {
  window.vuplex.addEventListener('message', function(event) {
    let json = event.data;
    // > JSON received: { "type": "greeting", "message": "Hello from C#!" }
    console.log('JSON received: ' + json);
  });
}

An alternative to passing messages from C# to JavaScript is to instead use IWebView.ExecuteJavaScript() to execute JavaScript directly.

Other examples

  • 3D WebView's AdvancedWebViewDemo scene demonstrates message passing from JavaScript to C# and vice versa.
  • 3D WebView's Keyboard UI is a React.js application that uses message passing to emit pressed characters and receive configuration data.