Setup: Headless
This guide covers sites whose pages are rendered by a separate front-end application. If your front end is rendered by dotCMS templates and layouts, see Traditional setup instead.
Supported today: Next.js (React) only
The headless integration is validated with Next.js using React and the dotCMS React SDK. Angular, Vue, Nuxt and other frameworks have not been tested and are not officially supported.
In headless mode there is no script injection. You activate analytics by installing the SDK and initializing it with the Site Auth for that domain.
The Content Analytics app still has to be configured on the site — that is where your Site Auth comes from, and events sent without a matching one are rejected. What does not carry over is everything below it: the Server-Rendered Pages Configuration toggles and the Advanced Configuration field have no effect here. All tracking behaviour is set in your application code.
Install and Configure#
npm install @dotcms/analytics// analytics.config.js
export const analyticsConfig = {
siteAuth: process.env.NEXT_PUBLIC_DOTCMS_ANALYTICS_SITE_KEY,
server: process.env.NEXT_PUBLIC_DOTCMS_ANALYTICS_HOST,
autoPageView: true,
debug: process.env.NEXT_PUBLIC_DOTCMS_ANALYTICS_DEBUG === 'true',
impressions: true,
clicks: true
};| Option | Required | Meaning | Default |
|---|---|---|---|
siteAuth | Yes | Site Auth from the Content Analytics app, for this domain. | — |
server | Yes | URL of the dotCMS instance that receives events. | — |
autoPageView | See the note below — behavior differs by integration. | false (standalone) | |
debug | Log analytics activity to the console. | false | |
impressions | Track content impressions. true, or an object to tune thresholds. | disabled | |
clicks | Track clicks on links and buttons inside content items. | disabled | |
queue | Event batching. An object to override, or false to send immediately. | 15 events / 5000 ms |
How page views actually fire
With the React <DotContentAnalytics> component, mounting it tracks a page view on every route change automatically via the Next.js App Router — the autoPageView flag does not gate this. With the standalone script, auto page view is off unless data-analytics-auto-page-view="true" is set. For manual control, call pageView() from the hook.
React and Next.js#
Place the component once in your root layout:
import { DotContentAnalytics } from '@dotcms/analytics/react';
import { analyticsConfig } from '@/config/analytics.config';
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<DotContentAnalytics config={analyticsConfig} />
{children}
</body>
</html>
);
}Use the useContentAnalytics hook to send events from any component. It exposes pageView(customData?), track(eventName, properties?) and conversion(name).
const { track, pageView, conversion } = useContentAnalytics(analyticsConfig);
const onPurchase = async () => {
const ok = await completePurchase(product);
if (ok) conversion('purchase'); // only AFTER it succeeds
};Making Content Trackable#
The React SDK handles this for you
If you render content with the <Contentlet> component from @dotcms/react, the wrapper class and the tracking attributes are added automatically whenever analytics is active. Nothing to write.
If you render content your own way, add them yourself — clicks and impressions only fire inside an element that carries them:
<div className="dotcms-contentlet"
data-dot-identifier={content.identifier}
data-dot-inode={content.inode}
data-dot-title={content.title}
data-dot-type={content.contentType}
data-dot-basetype={content.baseType}>
{/* <a> and <button> elements inside are tracked when clicks are enabled */}
</div>Cross-Origin Requests#
In a headless setup your app and your dotCMS instance are usually on different origins — for example an app on www.example.com sending events to example-headless.dotcms.dev. Because the SDK posts JSON, the browser issues a CORS preflight (OPTIONS) before each batch, so your dotCMS instance must allow the app's origin, the POST method and the Content-Type header.
This means every batch costs two round trips rather than one — another reason to leave batching on rather than sending each event immediately.
Standalone Script: Unvalidated#
For non-React apps, load the script directly. It is framework-agnostic JavaScript and exposes window.dotAnalytics, but it has not been tested outside Next.js. Validate event delivery in your app before relying on it.
| Attribute | Meaning | Default |
|---|---|---|
data-analytics-auth | Required. Site Auth for this domain. | — |
data-analytics-server | dotCMS instance URL that receives events. | current origin |
data-analytics-auto-page-view | Auto-track page views. | false |
data-analytics-impressions | Track content impressions. | false |
data-analytics-clicks | Track content clicks. | false |
data-analytics-debug | Console debug logging. | false |
data-analytics-config | Advanced JSON config (queue, impression thresholds). | — |