Turn Your Website into an AI Agent
This guide covers every way to integrate Rover — from a single script tag to framework-specific npm setups. Watch the walkthrough above to see the end result.
Prerequisites
- A website you control
- A Rover Workspace account (sign in with Google)
- Your Site ID, public key (
pk_site_*), and optional siteKeyId from the Workspace
Script Tag (Simplest)
Use data attributes for a zero-JavaScript integration:
<script type="application/agent+json">{"a2w":"https://agent.rtrvr.ai/v1/a2w/runs","run":"https://agent.rtrvr.ai/v1/a2w/runs"}</script>
<script
src="https://rover.rtrvr.ai/embed.js?v=YOUR_SITE_KEY_ID"
async
data-site-id="YOUR_SITE_ID"
data-public-key="pk_site_YOUR_PUBLIC_KEY"
data-site-key-id="YOUR_SITE_KEY_ID"></script>Supported production bootstrap attributes: data-site-id, data-public-key, and data-site-key-id. Allowed domains, discovery, Activity, and policy live in Workspace config.
If you enable Public A2W Access in Workspace, the generated snippet includes the discovery marker automatically, so there is no extra manual HTML work beyond the snippet itself.
With the default domainScopeMode: 'registrable_domain', a plain yourdomain.com entry already allows the apex host and its subdomains. *.yourdomain.com is narrower and matches subdomains only.
Boot Script (Advanced Config)
For task routing, checkpointing, UI options, or other advanced settings, use the two-part snippet before </body>:
<script>
(function(){
var r = window.rover = window.rover || function(){
(r.q = r.q || []).push(arguments);
};
r.l = +new Date();
})();
rover('boot', {
siteId: 'YOUR_SITE_ID',
publicKey: 'pk_site_YOUR_PUBLIC_KEY',
allowedDomains: ['yourdomain.com'],
domainScopeMode: 'registrable_domain',
});
</script>
<script
src="https://rover.rtrvr.ai/embed.js?v=YOUR_SITE_KEY_ID"
async
data-site-id="YOUR_SITE_ID"
data-public-key="pk_site_YOUR_PUBLIC_KEY"
data-site-key-id="YOUR_SITE_KEY_ID"></script>The inline script queues commands until embed.js loads asynchronously. No commands are lost regardless of load order, and page load is never blocked.
Browser-first vs machine-first access
Rover exposes three public paths:
- Browser-first convenience:
?rover=...and?rover_shortcut=... - Machine-first protocol:
POST https://agent.rtrvr.ai/v1/a2w/runs - Chatbot URL-fetch protocol:
GET https://agent.rtrvr.ai/v1/a2w/runs?url=<site>&prompt=<task>&execution=cloud&format=markdown, plusrover_execand/v1/a2w/from-url
Use deep links when a human or browser-capable tool just needs Rover to run in the page. Use POST /v1/a2w/runs when an AI, CLI, or autonomous agent can send JSON. Use GET when a chatbot can only fetch URLs and needs Rover to execute in the hosted cloud browser.
POST https://agent.rtrvr.ai/v1/a2w/runs
Content-Type: application/json
{ "url": "https://example.com", "prompt": "book a flight" }The returned run URL supports JSON polling, SSE, NDJSON, continuation input, and cancel. Browser-capable runs may also include a clean receipt-based open URL plus an optional readable browserLink alias.
External AI callers do not need your siteId, publicKey, or siteKeyId.
npm Package
npm install @rtrvr-ai/roverimport { boot, shutdown } from '@rtrvr-ai/rover';
boot({
siteId: 'YOUR_SITE_ID',
publicKey: 'pk_site_YOUR_PUBLIC_KEY',
allowedDomains: ['yourdomain.com'],
domainScopeMode: 'registrable_domain',
});Use npm when you need TypeScript types, version pinning, or SPA lifecycle control.
Framework Guides
React / Next.js
import { useEffect } from 'react';
import { boot, shutdown } from '@rtrvr-ai/rover';
export function RoverWidget() {
useEffect(() => {
boot({
siteId: 'YOUR_SITE_ID',
publicKey: 'pk_site_YOUR_PUBLIC_KEY',
allowedDomains: ['yourdomain.com'],
domainScopeMode: 'registrable_domain',
});
return () => { shutdown(); };
}, []);
return null;
}Next.js requires an SSR guard since Rover needs window and document:
import dynamic from 'next/dynamic';
const RoverWidget = dynamic(() => import('./RoverWidget'), { ssr: false });Vue / Nuxt
<script setup>
import { onMounted, onUnmounted } from 'vue';
onMounted(async () => {
const { boot } = await import('@rtrvr-ai/rover');
boot({
siteId: 'YOUR_SITE_ID',
publicKey: 'pk_site_YOUR_PUBLIC_KEY',
allowedDomains: ['yourdomain.com'],
domainScopeMode: 'registrable_domain',
});
});
onUnmounted(async () => {
const { shutdown } = await import('@rtrvr-ai/rover');
shutdown();
});
</script>For Nuxt, create a client-only plugin at plugins/rover.client.ts.
WordPress / Shopify
Use the script tag snippet from above. Place it before </body> in your theme template or theme settings.
Configuration
Domain Security
| Option | Default | Description |
|---|---|---|
allowedDomains | [] | Hostnames or patterns where Rover may operate |
domainScopeMode | 'registrable_domain' | Plain example.com means apex + subdomains in registrable_domain; host_only makes plain entries exact-host only and blocks sibling subdomains unless you explicitly allow them |
Navigation
Rover handles tab behavior automatically. Outside-domain pages open in a new tab with notice, same-host navigation stays in the current tab unless the link explicitly asks for a new tab, and allowed-host hops use smart tab selection.
Task Routing
| Mode | Behavior |
|---|---|
act (default) | Execute actions immediately |
planner | Plan first, then execute |
auto | Rover selects the best route per task |
Set taskRouting.plannerOnActError: true (default in auto mode) to fall back to planning when direct execution fails.
Checkpointing
Enabled by default. Rover syncs session state to the cloud for crash recovery and cross-tab continuity. Set checkpointing.enabled: false to disable.
UI & Branding
| Option | Default | Description |
|---|---|---|
ui.agent.name | 'Rover' | Assistant name in the UI |
ui.shortcuts | [] | Suggested journeys shown to users |
ui.greeting | — | Greeting bubble config ({name} placeholder supported) |
ui.panel.resizable | true | Desktop drag resize plus tablet/phone snap heights with per-device memory |
ui.mascot.disabled | false | Disable the mascot video |
Content Security Policy (CSP)
No CSP header? No action needed — Rover works out of the box.
If you set CSP headers, add:
| Directive | Value | Why |
|---|---|---|
script-src | https://rover.rtrvr.ai blob: | SDK + Web Worker |
worker-src | blob: https://rover.rtrvr.ai | Worker execution |
connect-src | https://agent.rtrvr.ai | API calls |
style-src | 'unsafe-inline' | Shadow DOM styles |
font-src | https://rover.rtrvr.ai | Self-hosted Manrope font |
For strict CSP, self-host embed.js and worker/rover-worker.js from your own origin, then set workerUrl in your boot config. This eliminates all external domain requirements except connect-src for the API.
Testing Locally
Add localhost to your allowed domains in the Workspace. Verify:
- Rover widget appears on page load
- You can type a request and Rover identifies page elements
- Navigation policies behave as expected
- Actions execute correctly
Production Checklist
- Site key created with production domains only
-
allowedDomainsset correctly - Domain scope verified
- Tested on production domain
- CSP directives added (if applicable)
- Monitoring blocked host attempts in Workspace
Ongoing Management
From the Rover Workspace you can rotate keys, update domains, enable/disable keys, and monitor usage — all without redeploying code.
See the full API and configuration reference for events, client tools, multi-tab behavior, and more.
