# Script Monitoring AI setup guide

Add Script Monitoring to this project. Script Monitoring is client-side security monitoring: one script tag, loaded first in the page's `<head>`, inventories the third-party scripts that run in visitors' browsers, so they can be scored, alerted on and blocked.

## Step 1: get this team's script URL (required)

Do not change any file until you have the user's real script URL. It looks like `https://<TEAM_ID>.cdn.scriptmt.com/sm.js`, where `<TEAM_ID>` is the team ID: digits only, for example a 14-digit number starting with 1.

1. **Look in the prompt that sent you here.** The Script Monitoring dashboard adds it as "Use this script URL: …". If it is there, use it exactly.
2. **If it is missing, stop and ask the user** for their Script Monitoring script URL or team ID. Tell them where to find it: in the Script Monitoring dashboard, open **Developers > Setup**, step 3 (**Install**); the script URL is shown there, and the team ID is also in the top bar next to **Team ID**. If they only give a team ID, build the URL as `https://<TEAM_ID>.cdn.scriptmt.com/sm.js`.
3. **Never guess or invent a team ID, and never use the documentation examples** `14827391650423`, `13069584217736` or organization `11938475026617`: they are reserved, never belong to a live customer, and the install tools reject them. Never reuse any other example value either, never use the website's own domain, and never leave a placeholder such as `<TEAM_ID>` in the code.
4. **Check the format.** The team ID must be digits only, and the URL must match `https://<digits>.cdn.scriptmt.com/sm.js` exactly. If it does not, ask the user again.
5. **Verify that it is live** if you can run commands: `curl -sI https://<TEAM_ID>.cdn.scriptmt.com/sm.js`. A valid team returns `200` with `content-type: application/javascript`. A `403` means the team ID is wrong: tell the user and ask them to copy it again from Developers > Setup. Do not continue with a team ID that returns 403.

Below, `<SCRIPT_URL>` is the verified script URL and `<TEAM_ID>` is the team ID taken from it.

## Rules

- Detect which framework this project uses and pick the matching method below.
- The Script Monitoring script must load before every other script on the page: first in the `<head>`, synchronous, with no `async` and no `defer`.
- Keep `referrerpolicy="origin"` on the tag.
- Do not remove or reorder any existing scripts.
- Add the tag once. If a Script Monitoring tag (`*.cdn.scriptmt.com/sm.js`) is already there, update its URL instead of adding a second one.

## Next.js (App Router or Pages Router)

1. Install the package: `npm i @scriptmonitoring/next` (or `yarn add` / `pnpm i`).
2. Pages Router, in `pages/_document.tsx`, render the component inside `<Head>`:
   ```tsx
   import { Html, Head, Main, NextScript } from 'next/document';
   import { ScriptMonitoringScript } from '@scriptmonitoring/next';

   export default function Document() {
     return (
       <Html lang="en">
         <Head>
           <ScriptMonitoringScript scriptURLOverride="<SCRIPT_URL>" />
         </Head>
         <body>
           <Main />
           <NextScript />
         </body>
       </Html>
     );
   }
   ```
3. App Router, in the root layout, render it before `{children}`:
   ```tsx
   import { ScriptMonitoringScript } from '@scriptmonitoring/next';

   export default function Layout({ children }) {
     return (
       <>
         <ScriptMonitoringScript scriptURLOverride="<SCRIPT_URL>" />
         {children}
       </>
     );
   }
   ```

`ScriptMonitoringScript` also accepts `teamId="<TEAM_ID>"`, which builds the same URL. Do not use `next/script` for this tag.

## Vite (React, Vue, Svelte, SolidJS and others)

1. Install the plugin: `npm i @scriptmonitoring/vite`.
2. Register it in `vite.config.ts`:
   ```ts
   import { scriptMonitoring } from '@scriptmonitoring/vite';
   import { defineConfig } from 'vite';

   export default defineConfig({
     plugins: [scriptMonitoring({ teamId: '<TEAM_ID>' }) /* , ...other plugins */],
   });
   ```

The plugin injects the tag at the start of `<head>` in production builds. It is off in the dev server unless you pass `enabled: true`.

## Static sites and other builds that output HTML (Astro, Gatsby, Hugo, Eleventy, Docusaurus and others)

Run the CLI after the build step, for example in `package.json`:

```json
"build": "your-existing-build && npm_config_yes=true npx @scriptmonitoring/cli@latest --team-id <TEAM_ID>"
```

The CLI processes `dist` (or `.next`) by default. Pass `--dir <folder>` for another output folder. It removes any Script Monitoring tag it injected before and adds the current one, so re-running is safe.

## Plain HTML or any other framework

Add this as the first element inside `<head>` of every page or of the HTML shell:

```html
<script type="text/javascript" src="<SCRIPT_URL>" referrerpolicy="origin"></script>
```

## Content Security Policy

After adding the tag, check whether the project sets a Content-Security-Policy. Look in:

- HTTP response headers (server config, middleware, `next.config.js` headers, `vercel.json`, `netlify.toml`, `_headers`)
- `<meta http-equiv="Content-Security-Policy">` tags
- security packages such as helmet

If a policy exists:

- If `script-src` (or `default-src`) only allows a list of hosts, add `*.cdn.scriptmt.com` to `script-src`.
- If `connect-src` (or `default-src`) only allows a list of hosts, add `*.cdn.scriptmt.com` to `connect-src`, because the script sends its findings back to that host.
- Broad sources such as `https:` already allow it.
- Only extend directives that already exist. Do not remove any directive or host.

## When you are done

Before you finish, confirm that every place you added uses the user's real `<SCRIPT_URL>` or `<TEAM_ID>`, with no placeholder left. Then tell the user which team ID you used, and ask them to deploy, load a page on the site, and open Developers > Setup, step 5 (Verify), in the Script Monitoring dashboard. Each domain the tag runs on must be listed under Security > Domains. Full documentation: https://docs.scriptmonitoring.com/install/
