Proxy Recording Endpoints
If you wish to avoid exposing the api.rrweb.com recording endpoints in the browser, then it is possible to proxy them with some plumbing.
Motivations
- Technical: there may be CORS issues with sending requests to third party domains
- Avoid blocking: in the event that
api.rrweb.commakes it onto a list of analytics providers - Compliance: your service needs to only use pre-approved domains in e.g. a GDPR jurisdiction. We use EU datacenters by default and can set up any additional compliance requirements on our backend after proxying.
Recommended: Setting up a dedicated subdomain
Setting up a separate subdomain for rrweb Cloud recording is the most straightforward method of directing requests to us. This can be accomplished by adding a CNAME record to the DNS configuration for your domain. Your hosting provider will provide a guide on how to do this.
;; Sample DiG output:
events.my-domain.com. 86400 IN CNAME api.rrweb.com.We've used events as the subdomain in this example, but you can use anything. After that goes live, point the browser client at your own subdomain:
<script type="module">
import { start } from 'https://cdn.rrweb.com/browser-client/next/browser-client.js';
start({
publicApiKey: 'your-public-api-key-here',
serverUrl:
'https://events.my-domain.com/recordings/{recordingId}/events/ws',
});
</script>Final step: let us know what subdomain you've used so we can allow-list it.
Forwarding the entire subdomain means that the individual API endpoints mentioned below will also be accessible, for example rrwebcloud.my-domain.com/recordings/{recordingId}/events/ws.
Server config for path proxying
INFO
The rest of this guide is only relevant if you cannot or do not wish to do CNAME forwarding, e.g. if you don't have access to the DNS system for the website. The following details are given as a sketch, and the rrweb Cloud team are on hand to help you set this up for the first time.
Configuring a serverUrl
The default serverUrl for the Browser Client is https://api.rrweb.com/recordings/{recordingId}/events/ws. Script-tag installs can also infer that value from the hosted script URL when it is omitted.
You can supply a different value in the starting config by setting the serverUrl param. In this example we've used my-domain.com/proxy as the sample endpoint you require:
"serverUrl": "https://my-domain.com/proxy/{recordingId}/events/ws"The above will necessitate the proxying of an additional URLs pattern which is derived from the above serverUrl value:
https://my-domain.com/proxy/([0-9a-f])+/events/ws(for websockets)https://my-domain.com/proxy/([0-9a-f])+/events(for POST requests)
Here is some example nginx config:
location ~ /proxy/(?<recordingId>.+)/events/ws {
proxy_pass https://api.rrweb.com/recordings/$recordingId/events/ws;
# websocket upgrade headers:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location ~ /proxy/(?<recordingId>.+)/events {
proxy_pass https://api.rrweb.com/recordings/$recordingId/events;
proxy_set_header Host $host;
}Get in contact to with us to help set this up with you.
Proxying the <script> url
If you are including the browser client using a script tag from the Browser Client and you wish to serve the JavaScript file from your own domain, then it is important that the file is proxied rather than copied to your server, as we will be regularly updating the file in lockstep with changes to our backend servers.
If you proxy the UMD global build, e.g. by serving <script src="https://my-domain.com/record.umd.min.cjs" autostart async>, then the JavaScript file will check its own URL and will use the following URL patterns unless you supply an explicit serverUrl:
# proxy the js you have specified in the <script> tag above
location ~ /record.umd.min.cjs {
proxy_pass https://cdn.rrweb.com/browser-client/next/browser-client.umd.min.cjs;
}
# these paths are autogenerated without an explicit `serverUrl` param
location ~ /recordings/(?<recordingId>.+)/events/ws {
proxy_pass https://api.rrweb.com/recordings/$recordingId/events/ws;
# websocket upgrade headers:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location ~ /recordings/(?<recordingId>.+)/events {
proxy_pass https://api.rrweb.com/recordings/$recordingId/events;
proxy_set_header Host $host;
}Omitting the {recordingId} pattern
Note: the special {recordingId} part of the URL will be replaced by an actual UUID when it is used. If you need to omit this, then the recordingId will be added as a GET parameter instead. This would need to be transformed by the proxy server into the correct URL pattern as shown in the examples above, but a recordingId in the GET is otherwise currently not implemented by our backend.