Skip to main content
This guide covers how to install Userplane in an Astro application.

Adding the script

The fastest way to add Userplane is the CDN embed. Add these two tags to the <head> of your base layout:
---
// src/layouts/Layout.astro
---

<html lang="en">
  <head>
    <meta name="userplane:workspace" content="YOUR_WORKSPACE_ID" />
    <script type="module" src="https://cdn.userplane.io/embed/script.js"></script>
  </head>
  <body>
    <slot />
  </body>
</html>
You can copy the snippet with your workspace ID pre-filled from Workspace Settings > Domains in the Userplane dashboard.

npm SDK

Use the npm SDK when you need programmatic control — triggering recordings from a button, attaching user metadata, or reading recording state.

Installation

npm install @userplane/sdk

Initialization

Add a <script> block to your base layout. In Astro, <script> blocks in .astro files are bundled and run in the browser — no client: directive or SSR guard is needed.
---
// src/layouts/Layout.astro
const workspaceId = import.meta.env.PUBLIC_USERPLANE_WORKSPACE_ID;
---

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <slot name="head" />
  </head>
  <body>
    <slot />

    <script>
      import { initialize } from '@userplane/sdk';

      initialize({
        workspaceId: import.meta.env.PUBLIC_USERPLANE_WORKSPACE_ID,
      });
    </script>
  </body>
</html>
Set the variable in your .env file:
PUBLIC_USERPLANE_WORKSPACE_ID=ws_abc123
import.meta.env.PUBLIC_* variables are inlined at build time by Vite. Access them inside <script> blocks (client-side), not in the frontmatter (server-side) — frontmatter runs at build/request time and has no access to browser APIs.

URL parameters

Astro can be deployed as a static site or with a server adapter (SSR). For static deployments, Userplane reads URL parameters on the client automatically — no additional configuration is needed. For SSR deployments with redirects, preserve the userplane- prefixed parameters through any server-side redirect in your middleware:
// src/middleware.ts
import { defineMiddleware } from 'astro:middleware';

export const onRequest = defineMiddleware((context, next) => {
  if (!isAuthenticated(context) && requiresAuth(context.url.pathname)) {
    const loginUrl = new URL('/login', context.url.origin);

    for (const [key, value] of context.url.searchParams) {
      if (key.startsWith('userplane-')) {
        loginUrl.searchParams.set(key, value);
      }
    }

    return context.redirect(loginUrl.toString());
  }

  return next();
});
See Installation for the full list of parameters.

Sensitive data

Add data-userplane-blur to any element you want blurred in recordings. See Sensitive Data Redaction for the full reference.

Metadata

Call set() inside the <script> block after initialize():
<script>
  import { initialize, set } from '@userplane/sdk';

  initialize({ workspaceId: import.meta.env.PUBLIC_USERPLANE_WORKSPACE_ID });
  set('environment', import.meta.env.MODE);
</script>
See Metadata SDK for the full API.

SSR

Astro’s <script> blocks are always client-only — Astro bundles them separately from the server render. The frontmatter section (---) runs on the server (or at build time for static output) and has no access to window, document, or browser APIs.
ContextRuns whereCan call initialize()?
Frontmatter (---)Server / build timeNo
<script> blockBrowserYes
Framework component with client:loadBrowserYes
Framework component without client:*Server onlyNo
@userplane/sdk is SSR-safe to import at the module level inside a <script> block. The module does not reference window at evaluation time.

Example app

A complete Astro example is available at github.com/wizenheimer/userplane-sdk-examples/tree/main/examples/astro.
VariableDescription
PUBLIC_USERPLANE_WORKSPACE_IDYour Userplane workspace ID
cd examples/astro && npm install && npm run dev