Next.js
Install the Coframe SDK in a Next.js app (App Router or Pages Router)
Copy this guide and your current settings as a prompt for your AI agent.
Preview agent promptSee the guide, code and settings included when you copy.
This guide covers adding Coframe to a Next.js application. Because Next.js
renders on the server before hydrating on the client, Coframe uses a
waitForHydration flag so variant changes are applied only after React has
fully mounted. Choose the section below that matches your router.
Set your project ID and options in the editor. Then follow the steps below using the updated code.
Open the editor to correct your Project ID before copying the installation code.
01App Router
Step 1 — Create the Coframe component
Create components/Coframe.tsx. This client component injects the Coframe
installation script via dangerouslySetInnerHTML and fires a pageHydrated
event after React mounts.
Replace YOUR_PROJECT_ID with the project ID from your Coframe dashboard.
"use client"
import { useEffect } from 'react'
export default function Coframe() {
// Send page hydrated event
useEffect(() => {
window.CFQ = window.CFQ || [];
window.CFQ.push({ pageHydrated: true })
}, [])
return (
<>
<script dangerouslySetInnerHTML={{
__html: `
(function () {
// Early exit for performance testing
if (/cf_disable/.test(location.search)) return console.warn('[Coframe] Disabled via URL parameter');
// Coframe config
const config = {
projectId: 'YOUR_PROJECT_ID',
startTime: Date.now(),
timeoutMs: 1000,
currentUrl: window.location.href,
waitForHydration: true, // Wait for the framework readiness signal
};
// Prevent duplicate installation
const script_id = 'coframe-sdk-js';
if (document.getElementById(script_id)) return console.warn('[Coframe] SDK already installed');
// Coframe queue setup
(window.CFQ = window.CFQ || []).push({ config });
// Coframe antiflicker CSS
const style = document.createElement('style');
style.id = 'coframe-antiflicker';
style.textContent =
':root { --cf-show: 0;}' +
'body { opacity: var(--cf-show) !important; transition: opacity 0.2s ease; }'
function hide() { document.head.appendChild(style); }
function show() {
document.documentElement.style.setProperty('--cf-show', '1');
style.parentNode && style.parentNode.removeChild(style);
}
hide(); setTimeout(show, config.timeoutMs);
// Coframe SDK JS
var edgeUrl = new URL('https://edge.cofra.me/cf.js');
edgeUrl.searchParams.set('config', encodeURIComponent(JSON.stringify(config)));
const script = document.createElement('script');
script.id = script_id;
script.async = true;
script.src = edgeUrl.toString();
script.onerror = () => { show(); console.error('[Coframe] SDK failed to load'); };
document.head.appendChild(script);
})();
`
}} />
</>
)
}Step 2 — Update your layout file
Import <Coframe /> in your root layout and render it inside <body> so it
runs on every page.
import Coframe from './components/Coframe'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<Coframe />
{children}
</body>
</html>
)
}02Pages Router
Step 1 — Update _document.tsx
Add the Coframe installation script to your custom _document.tsx using
next/script with strategy="beforeInteractive" so it runs before hydration.
Add the Script import and the <Script> block to your existing
_document.tsx. The ... stands in for your existing document structure (the
Html, Main, and NextScript parts).
import Script from 'next/script'
import { Head } from 'next/document'
...
<Head>
<Script id='coframe-setup' strategy="beforeInteractive">
{`
(function () {
// Early exit for performance testing
if (/cf_disable/.test(location.search)) return console.warn('[Coframe] Disabled via URL parameter');
// Coframe config
const config = {
projectId: 'YOUR_PROJECT_ID',
startTime: Date.now(),
timeoutMs: 1000,
currentUrl: window.location.href,
waitForHydration: true, // Wait for the framework readiness signal
};
// Prevent duplicate installation
const script_id = 'coframe-sdk-js';
if (document.getElementById(script_id)) return console.warn('[Coframe] SDK already installed');
// Coframe queue setup
(window.CFQ = window.CFQ || []).push({ config });
// Coframe antiflicker CSS
const style = document.createElement('style');
style.id = 'coframe-antiflicker';
style.textContent =
':root { --cf-show: 0;}' +
'body { opacity: var(--cf-show) !important; transition: opacity 0.2s ease; }'
function hide() { document.head.appendChild(style); }
function show() {
document.documentElement.style.setProperty('--cf-show', '1');
style.parentNode && style.parentNode.removeChild(style);
}
hide(); setTimeout(show, config.timeoutMs);
// Coframe SDK JS
var edgeUrl = new URL('https://edge.cofra.me/cf.js');
edgeUrl.searchParams.set('config', encodeURIComponent(JSON.stringify(config)));
const script = document.createElement('script');
script.id = script_id;
script.async = true;
script.src = edgeUrl.toString();
script.onerror = () => { show(); console.error('[Coframe] SDK failed to load'); };
document.head.appendChild(script);
})();
`}
</Script>
</Head>Step 2 — Create the Coframe component
Create components/Coframe.tsx. This component fires the pageHydrated event
once React has mounted.
import React, { useEffect } from 'react';
function Coframe() {
// Send page hydrated event
useEffect(() => {
window.CFQ = window.CFQ || [];
window.CFQ.push({ pageHydrated: true })
}, [])
return null;
}
export default Coframe;Step 3 — Add Coframe to _app.tsx
Import and render <Coframe /> in your custom _app.tsx so it appears on
every page.
import Coframe from '../components/Coframe';
export default function App({ Component, pageProps }) {
return (
<>
<Coframe />
<Component {...pageProps} />
</>
);
}03Verify it is working
After running your app and loading a page in a browser:
- Open the browser console and confirm there are no
[Coframe]error messages. - In the Network tab, look for a request to
edge.cofra.me/cf.js. A successful200response means the SDK loaded correctly. - Check that a
coframe-sdk-jsscript element appears in the DOM (you can inspect the<head>in the Elements panel).
For a full walkthrough of how to validate the integration and confirm that Coframe is operating as expected, see Testing and Validation.
04Optional configuration
The default script is designed to work without additional configuration. Once the SDK is installed, you can tune behavior using the following guides:
- SDK options — timeout, disable conditions, and other core settings
- Identity settings — associate SDK activity with a known user identity
- Tracking settings — control which events and page interactions Coframe records
- Anti-flicker — understand how the anti-flicker mechanism works and how to adjust it for your performance requirements
# Next.js
Install the Coframe SDK in a Next.js app (App Router or Pages Router)
This guide covers adding Coframe to a Next.js application. Because Next.js
renders on the server before hydrating on the client, Coframe uses a
`waitForHydration` flag so variant changes are applied only after React has
fully mounted. Choose the section below that matches your router.
[Video: Video: installing on the App Router and the Pages Router, and verifying in DevTools (65s, narrated)](assets/videos/fig10-install-nextjs.mp4)
Watch: 65s — installing on the App Router and the Pages Router, and verifying in DevTools
## App Router
Step 1 — Create the Coframe component
Create `components/Coframe.tsx`. This client component injects the Coframe
installation script via `dangerouslySetInnerHTML` and fires a `pageHydrated`
event after React mounts.
Replace `YOUR_PROJECT_ID` with the project ID from your Coframe dashboard.
TSX
```tsx
"use client"
import { useEffect } from 'react'
export default function Coframe() {
// Send page hydrated event
useEffect(() => {
window.CFQ = window.CFQ || [];
window.CFQ.push({ pageHydrated: true })
}, [])
return (
<>
<script dangerouslySetInnerHTML={{
__html: `
(function () {
// Early exit for performance testing
if (/cf_disable/.test(location.search)) return console.warn('[Coframe] Disabled via URL parameter');
// Coframe config
const config = {
projectId: 'YOUR_PROJECT_ID',
startTime: Date.now(),
timeoutMs: 1000,
currentUrl: window.location.href,
waitForHydration: true, // Wait for the framework readiness signal
};
// Prevent duplicate installation
const script_id = 'coframe-sdk-js';
if (document.getElementById(script_id)) return console.warn('[Coframe] SDK already installed');
// Coframe queue setup
(window.CFQ = window.CFQ || []).push({ config });
// Coframe antiflicker CSS
const style = document.createElement('style');
style.id = 'coframe-antiflicker';
style.textContent =
':root { --cf-show: 0;}' +
'body { opacity: var(--cf-show) !important; transition: opacity 0.2s ease; }'
function hide() { document.head.appendChild(style); }
function show() {
document.documentElement.style.setProperty('--cf-show', '1');
style.parentNode && style.parentNode.removeChild(style);
}
hide(); setTimeout(show, config.timeoutMs);
// Coframe SDK JS
var edgeUrl = new URL('https://edge.cofra.me/cf.js');
edgeUrl.searchParams.set('config', encodeURIComponent(JSON.stringify(config)));
const script = document.createElement('script');
script.id = script_id;
script.async = true;
script.src = edgeUrl.toString();
script.onerror = () => { show(); console.error('[Coframe] SDK failed to load'); };
document.head.appendChild(script);
})();
`
}} />
</>
)
}
```
Step 2 — Update your layout file
Import `<Coframe />` in your root layout and render it inside `<body>` so it
runs on every page.
TSX
```tsx
import Coframe from './components/Coframe'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body>
<Coframe />
{children}
</body>
</html>
)
}
```
## Pages Router
Step 1 — Update `_document.tsx`
Add the Coframe installation script to your custom `_document.tsx` using
`next/script` with `strategy="beforeInteractive"` so it runs before hydration.
Add the `Script` import and the `<Script>` block to your existing
`_document.tsx`. The `...` stands in for your existing document structure (the
`Html`, `Main`, and `NextScript` parts).
TSX
```tsx
import Script from 'next/script'
import { Head } from 'next/document'
...
<Head>
<Script id='coframe-setup' strategy="beforeInteractive">
{`
(function () {
// Early exit for performance testing
if (/cf_disable/.test(location.search)) return console.warn('[Coframe] Disabled via URL parameter');
// Coframe config
const config = {
projectId: 'YOUR_PROJECT_ID',
startTime: Date.now(),
timeoutMs: 1000,
currentUrl: window.location.href,
waitForHydration: true, // Wait for the framework readiness signal
};
// Prevent duplicate installation
const script_id = 'coframe-sdk-js';
if (document.getElementById(script_id)) return console.warn('[Coframe] SDK already installed');
// Coframe queue setup
(window.CFQ = window.CFQ || []).push({ config });
// Coframe antiflicker CSS
const style = document.createElement('style');
style.id = 'coframe-antiflicker';
style.textContent =
':root { --cf-show: 0;}' +
'body { opacity: var(--cf-show) !important; transition: opacity 0.2s ease; }'
function hide() { document.head.appendChild(style); }
function show() {
document.documentElement.style.setProperty('--cf-show', '1');
style.parentNode && style.parentNode.removeChild(style);
}
hide(); setTimeout(show, config.timeoutMs);
// Coframe SDK JS
var edgeUrl = new URL('https://edge.cofra.me/cf.js');
edgeUrl.searchParams.set('config', encodeURIComponent(JSON.stringify(config)));
const script = document.createElement('script');
script.id = script_id;
script.async = true;
script.src = edgeUrl.toString();
script.onerror = () => { show(); console.error('[Coframe] SDK failed to load'); };
document.head.appendChild(script);
})();
`}
</Script>
</Head>
```
Step 2 — Create the Coframe component
Create `components/Coframe.tsx`. This component fires the `pageHydrated` event
once React has mounted.
TSX
```tsx
import React, { useEffect } from 'react';
function Coframe() {
// Send page hydrated event
useEffect(() => {
window.CFQ = window.CFQ || [];
window.CFQ.push({ pageHydrated: true })
}, [])
return null;
}
export default Coframe;
```
Step 3 — Add Coframe to `_app.tsx`
Import and render `<Coframe />` in your custom `_app.tsx` so it appears on
every page.
TSX
```tsx
import Coframe from '../components/Coframe';
export default function App({ Component, pageProps }) {
return (
<>
<Coframe />
<Component {...pageProps} />
</>
);
}
```
## Verify it is working
After running your app and loading a page in a browser:
- Open the browser console and confirm there are no `[Coframe]` error messages.
- In the Network tab, look for a request to `edge.cofra.me/cf.js`. A
successful `200` response means the SDK loaded correctly.
- Check that a `coframe-sdk-js` script element appears in the DOM (you can
inspect the `<head>` in the Elements panel).
For a full walkthrough of how to validate the integration and confirm that
Coframe is operating as expected, see
[Testing and Validation](../docs/testing-and-validation.html).
## Optional configuration
The default script is designed to work without additional configuration. Once the
SDK is installed, you can tune behavior using the following guides:
- [SDK options](../docs/sdk-options.html) — timeout, disable conditions,
and other core settings
- [Identity settings](../docs/identity-settings.html) — associate SDK
activity with a known user identity
- [Tracking settings](../docs/tracking-settings.html) — control which
events and page interactions Coframe records
- [Anti-flicker](../docs/anti-flicker.html) — understand how the anti-flicker
mechanism works and how to adjust it for your performance requirements