Serving Pages with WebR

For performance and security reasons, web pages that load webR should be served with certain HTTP headers so that the page is cross-origin isolated. This allows the SharedArrayBuffer based communication channel to be used.

To ensure a web page is cross-origin isolated, serve the page with both the COOP and COEP HTTP headers set,

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

If successful, the value of the global JavaScript property crossOriginIsolated should return true.

Warning

Without cross-origin isolation, webR will fall back to the ServiceWorker communication channel. With this channel there may be reduced performance or further setup required.

As an alternative, the PostMessage communication channel may be manually selected for use.

Example script to serve webR pages locally

The following simple R script will serve files locally from the current working directory with the required HTTP headers set. Ensure that your R installation has the httpuv package installed and then save the following R code in a new script named serve.R.

library(httpuv)
runServer(host = "127.0.0.1", port = 8080,
  app = list(
    staticPaths = list(
      "/" = staticPath(
        ".",
        headers = list(
          "Cross-Origin-Opener-Policy" = "same-origin",
          "Cross-Origin-Embedder-Policy" = "require-corp"
        )
      )
    )
  )
)

Run the script on your own machine, for example by executing Rscript serve.R in a terminal. Once running, you can access the contents of the current working directory at the URL http://127.0.0.1:8080.

Using the PostMessage channel

If it is not possible to set the HTTP headers for cross-origin isolation, e.g. you are using an external service such as GitHub Pages to host your web content, the PostMessage communication channel may instead be used.

Warning

Interruption of running R code and nested R REPLs (readline(), menu(), browser(), etc.) are unsupported when using the PostMessage communication channel.

Enable the PostMessage communication channel by explicitly setting WebROptions.channelType during webR initialisation:

import { WebR, ChannelType } from 'https://webr.r-wasm.org/latest/webr.mjs';
const webR = new WebR({
  channelType: ChannelType.PostMessage,
});

Using the service worker channel when loading from CDN

When loading webR from CDN and using the ServiceWorker communication channel, you must host your own versions of the webR worker scripts somewhere in the same origin as the page loading webR. Attempting to load a service worker cross-domain will be blocked by most browsers, for security reasons.

The contents of your worker scripts can simply wrap the workers hosted on the webR CDN. For example, your service worker script may simply contain,

importScripts('https://webr.r-wasm.org/latest/webr-serviceworker.js');

saved with the filename webr-serviceworker.js.

And your web worker script may simply contain,

importScripts('https://webr.r-wasm.org/latest/webr-worker.js');

saved with the filename webr-worker.js.

Serve the two files somewhere in the same origin and scope as your web page. Do not store the scripts in a subdirectory relative to the page, as the service worker’s scope would then be limited to that location.

Once the worker scripts are available on your server, configure webR by giving the URL of the directory containing the scripts as the configuration option WebROptions.serviceWorkerUrl.