← Docs

Install Skate

One line, on every page of your app. It takes about three minutes.

1. Copy your line

In the Skate dashboard, open Settings › Sites and copy the line for your site. It looks like this:

html
<script src="https://cdn.useskate.com/skate.js" data-site="s_0123456789abcdef0123" async></script>

data-site is your site id. Each site is one web address (https://app.acme.com). The address in the browser’s bar must match it exactly: https://acme.com and https://www.acme.com are two sites.

2. Paste it before </head>

In the HTML that every page uses (your layout or template), paste the line just before </head>. Then deploy.

It is safe anywhere in the page: in <head> or <body>, with async or defer, or added by a tag manager. It loads after your page, never blocks it, and runs once even if the line is on the page twice.

Not your job? Use Send to my developer on the same page. It emails them the line and these steps.

3. Check it

Open your app in a new tab. The Skate launcher appears in the corner. The dashboard shows Skate is on your site within a few seconds.

Nothing showed up? Open the browser console (right-click, Inspect, Console). Skate prints one line that starts with [Skate] and names the fix. See the table below.

Your framework

Paste the line where your app keeps its page template.

You useWhere the line goes
Plain HTML, Rails, Django, Laravel, Flask, PHPThe shared layout: app/views/layouts/application.html.erb, templates/base.html, resources/views/layouts/app.blade.php
React (Vite, Create React App)index.html, before </head>
Next.js App Routerapp/layout.tsx, see below
Next.js Pages Routerpages/_document.tsx, inside <Head>
Vue (Vite)index.html, before </head>
Nuxtnuxt.config.ts, see below
SvelteKitsrc/app.html, before %sveltekit.head%
Angularsrc/index.html, before </head>
Google Tag ManagerA Custom HTML tag with the line, trigger All Pages. A Skate tag template for the gallery is coming.
WordPressYour theme’s header (Appearance › Theme File Editor › header.php, before </head>) or any “insert header code” plugin. A Skate plugin for the WordPress directory is coming.
Webflow, FramerSite settings › Custom code › Head code

Next.js App Router (app/layout.tsx):

tsx
import Script from 'next/script';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <Script src="https://cdn.useskate.com/skate.js" data-site="s_0123456789abcdef0123" strategy="afterInteractive" />
      </body>
    </html>
  );
}

Nuxt (nuxt.config.ts):

ts
export default defineNuxtConfig({
  app: { head: { script: [{ src: 'https://cdn.useskate.com/skate.js', 'data-site': 's_0123456789abcdef0123', async: true }] } },
});

Single-page apps, Turbo and Hotwire need nothing extra. Skate follows route changes and stays on the page when the body is swapped.

Tell Skate who is signed in (optional)

After your own sign-in, call Skate.identify(). Skate then shows who asked, and you can target people by plan or role. See Identify your users.

Content-Security-Policy

If your site sends a Content-Security-Policy header, add Skate’s two hosts:

script-src  https://cdn.useskate.com;
connect-src https://api.useskate.com;

If your policy uses nonces, put the same nonce on the Skate line. Skate passes it on. No style-src, img-src, frame-src or unsafe-eval change is needed.

If something is still blocked, the console says which directive and which host: [Skate] Your Content-Security-Policy blocks Skate: add https://api.useskate.com to connect-src.

If it does not show

The console saysWhat to do
[Skate] Site s_… is registered for https://acme.com; this request came from https://www.acme.com.The page’s address is not the one you registered. Add it as a site in the dashboard (Settings › Sites), and use that site’s line on it.
[Skate] No site is registered as s_….The id on the line is wrong. Copy the line again from the dashboard.
[Skate] data-site="…" is not a site id.The id is missing or cut short. Copy the line again.
[Skate] Your Content-Security-Policy blocks Skate: add … to …Add that host to that directive (see CSP).
[Skate] Could not load https://cdn.useskate.com/….A proxy, a firewall or a CSP script-src stopped the file. Allow cdn.useskate.com.
[Skate] The account that owns s_… has no task credits left.Add credits on the Billing page. Until then visitors see “not available right now”.
Nothing at allThe line is not on this page yet. View the page source and search for skate.js.

Ad blockers. We test Skate’s files and requests against the default lists of uBlock Origin and Adblock Plus (EasyList, EasyPrivacy, uBlock filters and privacy). None of them block Skate. Those lists do block background “beacon” pings to other sites; Skate sends its events as a normal request first and uses a beacon only as a fallback, so nothing is lost.

Remove it. Delete the line and deploy. To remove it from a page without a reload, call Skate.uninstall().

Older lines keep working

A line from before October 2026 (walk-bootstrap.js with data-walk-site, data-walk-server, data-walk-mode) still works as it is. You do not need to change it.

Try it on your own site.

Sign up free: 500 task credits for your own site, and 10 requests a day to try Skate on any site.

Sign up free