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>
);
}