# Add RageLayer to a website

> Instructions for coding agents implementing RageLayer 2.1.3 in an existing project. Inspect the project first, use its existing framework and package manager, make RageLayer explicitly user-triggered, and verify the real interaction in a browser.

## Goal

Add a visible, accessible launcher that lets a visitor open RageLayer, use its destructible-page tools, and close it to restore the original DOM. Integrate with the host application's conventions instead of restructuring the application around the library.

## Implementation workflow

1. Inspect the nearest package manifest, lockfile, framework version, application shell, component conventions, and existing test commands.
2. Install `ragelayer` with the package manager already used by the project. Do not introduce a second lockfile.
3. Choose exactly one integration below. Prefer the framework's first-class adapter over a hand-built wrapper.
4. Put the launcher in the user-requested scope. If no scope was specified, add it to the nearest relevant page or feature rather than every route.
5. Make opening an explicit user action. Do not auto-open RageLayer, especially for visitors who prefer reduced motion.
6. Keep the launcher outside the captured surface with `data-ragelayer-ignore`. Use a real `button` with a clear label.
7. Preserve one active engine per document. Use the adapter lifecycle or call `close()`/`dispose()` during teardown.
8. Run the host project's lint, type-check, test, and build commands, then exercise open, use, repair, and close in a real browser.

## Install

Use the command matching the existing lockfile:

```sh
npm install ragelayer
# pnpm add ragelayer
# yarn add ragelayer
# bun add ragelayer
```

The package is modern ESM with TypeScript declarations and no runtime dependencies. React, React DOM, and Vue are optional peer dependencies; do not add framework packages that the host does not already use.

## React

Use the complete toolbar component unless the requested design calls for custom controls:

```tsx
import { useState } from "react";
import { RageLayer } from "ragelayer/react";

export function DestroyButton() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <button
        type="button"
        data-ragelayer-ignore
        onClick={() => setOpen(true)}
      >
        Destroy this page
      </button>
      {open ? <RageLayer onClose={() => setOpen(false)} /> : null}
    </>
  );
}
```

The component disposes its engine on unmount. Use `useRageLayer` from `ragelayer/react` only when the host needs a custom toolbar.

## Next.js

Put the React integration in a Client Component. The published entry preserves its own `"use client"` boundary, but the launcher owns React state and must also be a client component. Do not call `open()` while rendering on the server.

```tsx
"use client";

import { useState } from "react";
import { RageLayer } from "ragelayer/react";

export function DestroyButton() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <button type="button" data-ragelayer-ignore onClick={() => setOpen(true)}>
        Destroy this page
      </button>
      {open && <RageLayer onClose={() => setOpen(false)} />}
    </>
  );
}
```

Lazy loading with `React.lazy` or `next/dynamic` is optional when the host needs zero RageLayer cost before the first click.

## Vue 3 / Nuxt

```vue
<script setup lang="ts">
import { ref } from "vue";
import { RageLayer } from "ragelayer/vue";

const open = ref(false);
</script>

<template>
  <button type="button" data-ragelayer-ignore @click="open = true">
    Destroy this page
  </button>
  <RageLayer v-if="open" @close="open = false" />
</template>
```

The component renders nothing until mounted and disposes on unmount. A click-driven Nuxt integration does not need `ClientOnly`. Use `onMounted` or `ClientOnly` only if the host intentionally opens it outside a user event.

## Svelte / SvelteKit

Use the action for a minimal launcher with custom controls:

```svelte
<script lang="ts">
  import { rageLayer } from "ragelayer/svelte";
</script>

<button
  type="button"
  data-ragelayer-ignore
  use:rageLayer={{ initialTool: "hammer" }}
>
  Destroy this page
</button>
```

The action toggles on repeated clicks, maintains `aria-pressed`, and closes during teardown. For the complete built-in toolbar, load `ragelayer/element` on mount and render a `<rage-layer>` custom element.

## Any other framework

For a complete toolbar in Astro, Angular, Solid, Qwik, or a bundled vanilla application, use the custom element:

```ts
import "ragelayer/element";

const rageLayer = document.createElement("rage-layer");
rageLayer.setAttribute("initial-tool", "hammer");
rageLayer.addEventListener("ragelayer-close", () => rageLayer.remove());
document.body.append(rageLayer);
```

For a custom UI, use the SSR-safe lazy controller:

```ts
import { createRageLayer } from "ragelayer";

const rageLayer = createRageLayer({ initialTool: "hammer" });
const launcher = document.querySelector<HTMLButtonElement>("#destroy");

launcher?.addEventListener("click", () => rageLayer.toggle());
const unsubscribe = rageLayer.subscribe((engine) => {
  if (launcher) launcher.ariaPressed = String(engine !== null);
});

// Run from the owning SPA lifecycle.
unsubscribe();
rageLayer.close();
```

Creating the lazy controller is server-safe. Calling `open()`, `toggle()`, `mountRageLayer()`, or constructing a live engine requires a browser document.

## Feature map

Fetch only the documentation needed for the requested feature:

- [Getting started](https://www.parthjadhav.com/products/ragelayer/docs/getting-started/index.md): install, first interaction, built-in tools, and keyboard shortcuts.
- [Framework integrations](https://www.parthjadhav.com/products/ragelayer/docs/integrations/index.md): full React, Next.js, Vue, Nuxt, Svelte, Astro, Angular, Solid, custom-element, and vanilla examples.
- [Toolbars, translation, and keyboard](https://www.parthjadhav.com/products/ragelayer/docs/toolbar/index.md): built-in toolbar options, custom controls, strings, shortcuts, and non-pointer operation.
- [API reference](https://www.parthjadhav.com/products/ragelayer/docs/api/index.md): engine options, lifecycle, capture, history, events, snapshots, and low-level methods.
- [Tool gallery](https://www.parthjadhav.com/products/ragelayer/docs/tools/index.md): all fifteen tool ids and gestures.
- [Advanced systems](https://www.parthjadhav.com/products/ragelayer/docs/advanced/index.md): selective tool imports, combos, undo/redo, and custom tools.
- [Performance](https://www.parthjadhav.com/products/ragelayer/docs/performance/index.md): quality tiers, lazy loading, telemetry, memory budgets, and fallbacks.
- [Compatibility](https://www.parthjadhav.com/products/ragelayer/docs/compatibility/index.md): browser support, ESM, SSR, CSP, and cross-origin capture.
- [Accessibility](https://www.parthjadhav.com/products/ragelayer/docs/accessibility/index.md): launcher responsibilities, keyboard limits, translation, and reduced motion.
- [Troubleshooting](https://www.parthjadhav.com/products/ragelayer/docs/troubleshooting/index.md): SSR, CORS capture, stacking, audio, multiple overlays, and performance failures.
- [Complete machine-readable docs index](https://www.parthjadhav.com/products/ragelayer/llms.txt): every RageLayer page in clean Markdown.

## Required behavior

- Keep RageLayer optional; no primary content or essential control may depend on the canvas interaction.
- Keep sound off unless the user or product requirements explicitly enable it from a user gesture.
- Do not weaken the host's Content Security Policy just to make optional WebGL or audio effects work. Follow the compatibility guide.
- Expect cross-origin images, fonts, stylesheets, or iframes without CORS headers to degrade snapshot capture. The overlay fallback should remain usable.
- Preserve the host's visual language for the launcher. RageLayer owns the overlay toolbar, not the surrounding page UI.
- Do not invent tool ids or API options. Confirm non-basic behavior against the versioned Markdown docs above.

## Verification

Confirm all of the following before handoff:

- Dependency installation used the existing package manager and changed only its expected manifest and lockfile.
- Server rendering, hydration, type-checking, linting, tests, and production build still pass where those checks exist.
- The launcher is keyboard reachable, clearly labelled, and excluded from capture.
- Opening creates one overlay; a tool can affect the page; repair restores it; close restores the original DOM and focus.
- Repeated open/close cycles do not leave canvases, scroll locks, audio, listeners, or duplicate toolbars behind.
- Narrow screens and `prefers-reduced-motion` remain usable.
- Any requested customization is backed by the versioned API documentation rather than an assumed interface.
