Next.js
Integrate with Next.js App Router or Pages Router
Step 1: Add the Script
Do not add to root layout
Do not add the script to your root app/layout.tsx or pages/_app.tsx — this loads the widget on every page, including public pages, and the auto-prompt will fire for anonymous visitors.
Instead, add it to your authenticated layout (e.g., app/(dashboard)/layout.tsx or a layout that wraps your logged-in area).
App Router (app directory)
Create or update your authenticated layout (e.g., app/(dashboard)/layout.tsx):
import Script from 'next/script';
export default function DashboardLayout({ children }) {
return (
<>
<Script
src="https://cdn.thewebratings.com/twr.min.js"
strategy="afterInteractive"
/>
{children}
</>
);
}Pages Router
Add to a layout component that wraps your authenticated pages (not _app.tsx):
import Script from 'next/script';
function DashboardLayout({ children }) {
return (
<>
<Script
src="https://cdn.thewebratings.com/twr.min.js"
strategy="afterInteractive"
/>
{children}
</>
);
}Step 2: Initialize in Component
App Router Example
'use client';
import { useEffect } from 'react';
export default function DashboardPage() {
useEffect(() => {
if (typeof window !== 'undefined' && window.TheWebRatings) {
window.TheWebRatings
.init({
apiKey: process.env.NEXT_PUBLIC_TWR_API_KEY || 'your-api-key',
debug: true
})
.then(() => console.log('TheWebRatings ready'))
.catch((err) => console.error('Initialization failed:', err));
}
}, []);
const openFeedback = () => {
// Pass logged-in user (e.g. from session or auth context)
window.TheWebRatings?.open('[email protected]', 'User Name');
};
return <button onClick={openFeedback}>Leave a Review</button>;
}Pages Router Example
import { useEffect } from 'react';
export default function DashboardPage() {
useEffect(() => {
if (typeof window !== 'undefined' && window.TheWebRatings) {
window.TheWebRatings
.init({ apiKey: process.env.NEXT_PUBLIC_TWR_API_KEY || 'your-api-key' })
.catch((err) => console.error('Initialization failed:', err));
}
}, []);
return (
<button onClick={() => window.TheWebRatings?.open('[email protected]', 'User Name')}>
Leave a Review
</button>
);
}Environment Variables
Add to .env.local:
NEXT_PUBLIC_TWR_API_KEY=your-api-keyCustom Hook (Optional)
Create hooks/useTheWebRatings.ts:
import { useEffect, useState } from 'react';
export function useTheWebRatings(apiKey: string) {
const [ready, setReady] = useState(false);
useEffect(() => {
if (typeof window === 'undefined' || !window.TheWebRatings) return;
window.TheWebRatings.init({ apiKey }).then(() => setReady(true)).catch(console.error);
}, [apiKey]);
const showWidget = (userEmail: string, userName?: string) => {
if (ready) window.TheWebRatings?.open(userEmail, userName);
};
return { ready, showWidget };
}Use it:
const { ready, showWidget } = useTheWebRatings(process.env.NEXT_PUBLIC_TWR_API_KEY!);
const user = useUser(); // your auth
return (
<button onClick={() => showWidget(user.email, user.name)} disabled={!ready}>
Leave a Review
</button>
);Tips
- Always check
typeof window !== 'undefined'for SSR safety - Use
process.env.NEXT_PUBLIC_*for client-side environment variables - Initialize once in your authenticated layout, not in every component — and not in the root layout
- The
strategy="afterInteractive"ensures the script loads after page hydration