Put analytics in app/layout.tsx when you want Rooster to track every route and enforce page-level bot protection globally.
import Script from "next/script";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script src="https://api.rooster.host/analytics/YOUR_PUBLIC_KEY.js" strategy="afterInteractive" />
</body>
</html>
);
}
Only put the form collector in the layout when every public form in the app should be collected.
import Script from "next/script";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script src="https://api.rooster.host/analytics/YOUR_PUBLIC_KEY.js" strategy="afterInteractive" />
<Script src="https://rooster.ink/embed/YOUR_PUBLIC_KEY.js" strategy="afterInteractive" />
</body>
</html>
);
}
Then map each form to a Rooster form group.
export function NewsletterForm() {
return (
<form data-rooster-form="default">
<input name="email" type="email" required />
<button type="submit">Subscribe</button>
</form>
);
}
Use this when the collector should only run on one route, such as /contact.
import Script from "next/script";
export default function ContactPage() {
return (
<>
<Script
src="https://rooster.ink/embed/YOUR_PUBLIC_KEY.js"
data-rooster-form="support"
strategy="afterInteractive"
/>
<form data-rooster-form="support">
<input name="email" type="email" required />
<textarea name="message" required />
<button type="submit">Send</button>
</form>
</>
);
}
The form collector saves partial progress when a visitor clicks a data-rooster-continue button.
"use client";
import { useState } from "react";
import Script from "next/script";
export default function DemoRequestPage() {
const [step, setStep] = useState(1);
return (
<>
<Script
src="https://rooster.ink/embed/YOUR_PUBLIC_KEY.js"
data-rooster-form="sales"
strategy="afterInteractive"
/>
<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>
) : null}
{step === 2 ? (
<section>
<select name="company_size" defaultValue="11-50">
<option>1-10</option>
<option>11-50</option>
<option>51-200</option>
</select>
<button type="button" data-rooster-continue onClick={() => setStep(3)}>
Next
</button>
</section>
) : null}
{step === 3 ? (
<section>
<textarea name="project_notes" />
<button type="submit" data-rooster-continue data-rooster-final="true">
Submit
</button>
</section>
) : null}
</form>
</>
);
}