RoosterDocs
Rooster Docs
Installation
Integrations
Examples
Plain HTMLNext.js App RouterReact SPAVue 3SvelteKitWebflowWixWordPressFramerSquarespace
Troubleshooting
HomeApp
Rooster Docs
RoosterDocs
Rooster Docs
Installation
Integrations
Examples
Plain HTMLNext.js App RouterReact SPAVue 3SvelteKitWebflowWixWordPressFramerSquarespace
Troubleshooting
HomeApp
Docs/React SPA

React SPA

Install Rooster in a client-rendered React app.

Analytics Only

Mount analytics once near the app root.

import { useEffect } from "react";
 
export function RoosterAnalytics() {
  useEffect(() => {
    const script = document.createElement("script");
    script.src = "https://api.rooster.host/analytics/YOUR_PUBLIC_KEY.js";
    script.defer = true;
    document.head.appendChild(script);
    return () => script.remove();
  }, []);
 
  return null;
}

Collect Every Form

Mount the collector once if all forms in the SPA should be collected.

import { useEffect } from "react";
 
export function RoosterCollector() {
  useEffect(() => {
    const script = document.createElement("script");
    script.src = "https://rooster.ink/embed/YOUR_PUBLIC_KEY.js";
    script.defer = true;
    document.head.appendChild(script);
    return () => script.remove();
  }, []);
 
  return null;
}

Basic Form

For one form group, mount the collector with the form key and add the same key to the form.

import { useEffect } from "react";
 
export function ContactForm() {
  useEffect(() => {
    const script = document.createElement("script");
    script.src = "https://rooster.ink/embed/YOUR_PUBLIC_KEY.js";
    script.defer = true;
    script.dataset.roosterForm = "support";
    document.head.appendChild(script);
    return () => script.remove();
  }, []);
 
  return (
    <form data-rooster-form="support">
      <input name="email" type="email" required />
      <textarea name="message" required />
      <button type="submit">Send</button>
    </form>
  );
}

Multi-Stage Form

import { useEffect, useState } from "react";
 
export function SalesForm() {
  const [step, setStep] = useState(1);
 
  useEffect(() => {
    const script = document.createElement("script");
    script.src = "https://rooster.ink/embed/YOUR_PUBLIC_KEY.js";
    script.defer = true;
    script.dataset.roosterForm = "sales";
    document.head.appendChild(script);
    return () => script.remove();
  }, []);
 
  return (
    <form data-rooster-form="sales">
      {step === 1 && (
        <section>
          <input name="work_email" type="email" required />
          <button type="button" data-rooster-continue onClick={() => setStep(2)}>
            Next
          </button>
        </section>
      )}
 
      {step === 2 && (
        <section>
          <input name="budget" type="text" />
          <button type="button" data-rooster-continue onClick={() => setStep(3)}>
            Next
          </button>
        </section>
      )}
 
      {step === 3 && (
        <section>
          <textarea name="project_notes" />
          <button type="submit" data-rooster-continue data-rooster-final="true">
            Submit
          </button>
        </section>
      )}
    </form>
  );
}
PreviousNext.js App RouterNextVue 3

On this page

Analytics OnlyCollect Every FormBasic FormMulti-Stage Form