npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@dotcms/events

v26.10.29-1

Published

Official JavaScript library for dotCMS events: pageviews, conversions, content clicks and impressions, and experiments.

Readme

dotCMS Events SDK

The @dotcms/events SDK is the official dotCMS library for everything your pages report back to dotCMS: pageviews, conversions, content impressions, content clicks, and A/B testing experiments. You configure it once, and a single object, dotEvents, takes care of the rest.

Overview

When to Use It

  • Measuring how visitors use your dotCMS-powered pages: which pages they visit, which content they see, and what they click
  • Recording conversions when a visitor completes a goal, such as a sign-up or a download
  • Running the A/B testing experiments you create in dotCMS on a headless site
  • Replacing @dotcms/analytics and @dotcms/experiments with a single package

Key Features

  • Automatic pageviews: on the first load, on every client-side navigation, and when the visitor comes back to a page with the browser's Back and Forward buttons
  • Content impressions: records which contentlets the visitor actually saw, and for how long they had to be on screen
  • Content clicks: records clicks on the links and buttons inside your contentlets
  • Conversions: one call when a visitor completes a goal
  • Experiments without flicker: sends each visitor to their variant, and keeps the content hidden for a moment so nobody sees the wrong one
  • One setup: one init call configures everything, and every module of your app uses the same object
  • No cookies: the SDK stores anonymous ids in the browser's storage, never in cookies
  • Safe in the editor: inside the dotCMS Universal Visual Editor (UVE), nothing is sent

Table of Contents

Installation

Install the package via npm:

npm install @dotcms/events

Or using Yarn:

yarn add @dotcms/events

Requirements:

  • A dotCMS instance with the Content Analytics app configured for your site. You need its Site Auth.
  • Next.js 16 or later, if you use Next.js.
  • React 18 or later, for DotCMSExperiment (@dotcms/events/react).

The package has three entry points:

| Import | What it gives you | Use it in | | ----------------------- | ------------------------------------------------------------------------- | ------------------------------------------ | | @dotcms/events | dotEvents: starts the SDK, records conversions and sends pageviews | Every app | | @dotcms/events/react | DotCMSExperiment: runs a page's experiment on the content it wraps | React and Next.js pages that run experiments | | @dotcms/events/markup | experimentMarkup: what a server-rendered page prints to run its experiment | Other frameworks, rendered on the server |

Which SDK Version Should I Use?

dotCMS SDKs are published in lockstep with dotCMS itself: every @dotcms/* package ships at the exact same version number as the dotCMS release it was built for (e.g. dotCMS 26.7.14-1 → @dotcms/[email protected], @dotcms/[email protected], and so on).

Simple rule of thumb: use the SDK version that matches your dotCMS instance's version.

You don't have to upgrade the SDK every time dotCMS releases a new version (or vice versa). Most releases don't change anything the SDKs rely on, so an older SDK usually keeps working fine against a newer dotCMS instance. Occasionally, though, a release does include a real breaking change — and if your SDK is older than that point, it will stop working correctly.

You don't need to track this yourself: your dotCMS instance always knows the oldest SDK version it still supports, and the SDK checks itself against it automatically. If you're using an SDK that's too old, you'll see a clear warning in your console telling you to upgrade.

Recommendation: pin your SDKs to the same version as your dotCMS instance, and only bump them when you upgrade dotCMS — or when the console tells you to.

On an LTS release? LTS releases don't currently get their own matching SDK version. Until that's addressed, use the SDK version published for the closest regular release at or before your LTS version.

Want more background on how dotCMS releases and support windows work? See Release & Support Lifecycle.

Quick Start (Next.js)

1. Add the environment variables

Add these to your .env.local file:

NEXT_PUBLIC_DOTCMS_HOST=https://your-dotcms-instance.com
NEXT_PUBLIC_DOTCMS_SITE_AUTH=your-site-auth

| Variable | Description | | ------------------------------ | ---------------------------------------------------------------- | | NEXT_PUBLIC_DOTCMS_HOST | The URL of your dotCMS instance | | NEXT_PUBLIC_DOTCMS_SITE_AUTH | The Site Auth from the Content Analytics app in dotCMS |

2. Start the SDK once

Create src/instrumentation-client.ts. Next.js runs this file once in the browser, before your app becomes interactive:

// src/instrumentation-client.ts
import { dotEvents } from '@dotcms/events';

dotEvents.init({
    dotcmsUrl: process.env.NEXT_PUBLIC_DOTCMS_HOST!,
    siteAuth: process.env.NEXT_PUBLIC_DOTCMS_SITE_AUTH!,
    impressions: true,
    clicks: true
});

That's all pageviews, impressions, clicks and experiments need. Impressions and clicks are optional; pageviews and experiments are on by default.

3. Record conversions

Import the same object wherever a visitor completes a goal, and record the conversion once it succeeds:

'use client';

import { dotEvents } from '@dotcms/events';

export function SignupForm() {
    const onSubmit = async (event: React.FormEvent) => {
        event.preventDefault();
        await createAccount(); // your own code

        // Only after the goal is reached, never on the attempt
        dotEvents.conversion('signup');
    };

    return <form onSubmit={onSubmit}>{/* fields */}</form>;
}

4. Run experiments on your pages

Wrap the content your experiments change in DotCMSExperiment, and pass the URL's variantName to the page request:

// src/app/[[...slug]]/page.tsx
import { DotCMSExperiment } from '@dotcms/events/react';

import { dotCMSClient } from '@/lib/dotCMSClient'; // your @dotcms/client instance

interface PageProps {
    params: Promise<{ slug?: string[] }>;
    searchParams: Promise<{ variantName?: string }>;
}

export default async function Page({ params, searchParams }: PageProps) {
    const { slug } = await params;
    const { variantName } = await searchParams;
    const path = slug?.length ? `/${slug.join('/')}` : '/';

    // variantName makes dotCMS render the visitor's variant
    const pageContent = await dotCMSClient.page.get(path, { variantName });

    return (
        <DotCMSExperiment page={pageContent.pageAsset}>
            <MyPage pageContent={pageContent} />
        </DotCMSExperiment>
    );
}

MyPage is your view of the page, for example one that renders it with DotCMSLayoutBody from @dotcms/react. On a page that runs no experiment, DotCMSExperiment renders its children as they are, so you can wrap every page the same way.

Example Project

The Next.js experiments example runs on this package. It shows:

  • The init call in instrumentation-client.ts, with the configuration in one file
  • Pageviews, impressions and clicks on every page
  • Experiments on the home page and on a blog listing, including content that streams in
  • A conversion from a contact form

How It Works

Pageviews

A pageview is sent when the page first loads, on every client-side navigation, and when the visitor returns to a page with the Back or Forward button. Each one carries the page's URL, title and locale, the campaign (UTM) parameters, and the visitor's device and screen.

To send them yourself instead, set autoPageView: false and call dotEvents.pageView().

Content Impressions

With impressions on, the SDK records each contentlet the visitor actually sees: at least half of it in view, for at least 750 ms. Each contentlet counts once per page view, and nothing counts while the tab is hidden or the window is behind others.

Impressions and clicks need the contentlets to carry dotCMS's attributes (the dotcms-contentlet class and its data-dot-* attributes). The dotCMS React, Angular and Vue SDKs add them on their own while this SDK is active, so pages rendered with DotCMSLayoutBody need nothing more.

Content Clicks

With clicks on, the SDK records clicks on the links and buttons inside your contentlets: which contentlet, the element's text and link, and where the contentlet sits on the page. Repeated clicks on the same contentlet within 300 ms count once.

Conversions

A conversion records that a visitor reached a goal. dotCMS stores its name and the page it happened on. Record it only once the goal is reached: a completed purchase, a finished download, a created account, not the click that started it.

Experiments

Experiments are on by default. When a visitor opens a page that runs an experiment:

  1. The content the experiment changes stays hidden for a moment, so the visitor never sees the wrong variant.
  2. The SDK asks dotCMS which variant the visitor gets, and remembers the answer in the browser.
  3. If the page shows another variant, the SDK sends the visitor to theirs: the same URL with ?variantName=<variant>.
  4. Otherwise it shows the content.

A returning visitor is sent to their variant right away, before the page finishes loading. If dotCMS takes more than 3 seconds to answer a new visitor, the original content shows, and the assignment applies from the next page on.

Events sent from a page that runs an experiment the visitor is in carry the experiment and the visitor's variant, together with the other experiments the visitor joined during the same session. Events from other pages carry none.

How Events Are Sent

Events are sent in batches: every 5 seconds, or as soon as 15 are waiting. When the visitor switches tabs, closes the tab or leaves the page, whatever is waiting goes out right away. Nothing is retried, and nothing the SDK does can throw an error into your page: failures go to onError.

Visitors and Sessions

Each visitor gets an anonymous id, kept in the browser's localStorage, and each visit a session id. A session ends after 30 minutes without activity, or at midnight (UTC). The SDK sets no cookies.

In the Universal Visual Editor

Inside the dotCMS Universal Visual Editor, the SDK sends nothing, and experiment content shows as it is, so editors can work on the page. On the server, every call does nothing.

Configuration

Config Options

| Option | Type | Required | Default | Description | | -------------- | ---------------------------------------- | -------- | ------- | --------------------------------------------------------------------------- | | dotcmsUrl | string | ✅ | — | The URL of your dotCMS instance, the same value createDotCMSClient takes | | siteAuth | string | ✅ | — | The Site Auth from the Content Analytics app | | autoPageView | boolean | ❌ | true | Send pageviews automatically | | experiments | boolean \| DotCMSEventsExperimentsConfig | ❌ | true | Run experiments; false turns them off | | impressions | boolean \| DotCMSEventsImpressionsConfig | ❌ | false | Record content impressions | | clicks | boolean | ❌ | false | Record content clicks | | queue | boolean \| DotCMSEventsQueueConfig | ❌ | true | Send events in batches; false sends each one at once | | debug | boolean | ❌ | false | Log what the SDK does to the browser console | | logLevel | 'debug' \| 'info' \| 'warn' \| 'error' | ❌ | — | The least important level the console shows | | onError | (error: DotCMSEventsError) => void | ❌ | — | Called when something fails that the page can't see |

Impressions

true turns impressions on with the defaults. An object changes them:

| Option | Default | Description | | --------------------- | ------- | ------------------------------------------------------------------ | | visibilityThreshold | 0.5 | How much of the contentlet must be in view, from 0 to 1 | | dwellMs | 750 | How long, in milliseconds, it must stay in view | | maxNodes | 100 | The most contentlets tracked on a page |

dotEvents.init({
    dotcmsUrl: process.env.NEXT_PUBLIC_DOTCMS_HOST!,
    siteAuth: process.env.NEXT_PUBLIC_DOTCMS_SITE_AUTH!,
    impressions: { visibilityThreshold: 0.7, dwellMs: 1000 }
});

Experiments

| Option | Default | Description | | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- | | timeout | 3000 | How long, in milliseconds, a new visitor's page waits for their variant before showing the original. 3000 is also the most: past it the content shows on its own |

Queue

| Option | Default | Description | | ---------------- | ------- | -------------------------------------------- | | eventBatchSize | 15 | The most events in one batch | | flushInterval | 5000 | How often, in milliseconds, a batch is sent |

Errors

onError receives what failed, with a code:

| Code | When | | ------------- | ------------------------------------------------------------------------------------------------------------ | | REJECTED | dotCMS refused an events request, or some of its events. status and detail say why | | NETWORK | An events request got no answer | | EXPERIMENTS | Asking dotCMS for the visitor's variant failed. A 403 means experiments are off for the site; the SDK stops asking for a day |

Alongside code it carries:

  • message (string): What went wrong.
  • status (number): The HTTP status, when dotCMS answered.
  • detail (unknown): What dotCMS said about the failure, for REJECTED.
  • events (number): How many events the failed request carried, for REJECTED and NETWORK.
dotEvents.init({
    dotcmsUrl: process.env.NEXT_PUBLIC_DOTCMS_HOST!,
    siteAuth: process.env.NEXT_PUBLIC_DOTCMS_SITE_AUTH!,
    onError: (error) => console.warn(`dotCMS events: ${error.code}`, error.message)
});

Usage

Next.js App Router

Follow the Quick Start. An experiment page also needs to:

  • Pass variantName to the page request. Without it, the variant's URL shows the original content.
  • Render on every request. Reading searchParams does that. A page built ahead of time can't run an experiment.
  • Use DotCMSExperiment in a server component when it can. It then adds no JavaScript to the browser; in a client component it adds about 1.5 KB.

Content that streams in, behind <Suspense> or loading.tsx, works too: the SDK decides it when it arrives. On a site with a nonce-based Content-Security-Policy, pass the nonce: <DotCMSExperiment page={pageAsset} nonce={nonce}>.

Other React Apps

Call init once, where your app starts, before it renders. DotCMSExperiment works the same way.

Other Frameworks

dotEvents works with any framework. To run experiments, print what experimentMarkup returns in the HTML your server sends:

import { experimentMarkup } from '@dotcms/events/markup';

const markup = experimentMarkup(pageAsset); // null when the page runs no experiment

// <style>{markup.style}</style>
// <script>{markup.script}</script>
// <div {...markup.attributes}>the content the experiment changes</div>

Traditional Pages

Pages dotCMS renders itself (VTL) don't need this package: dotCMS adds the tracking to them on its own. You turn it on and configure it in the Content Analytics app.

Plain Scripts

After init, any script on the page can reach the same object as window.dotEvents:

<script>
    window.dotEvents?.conversion('newsletter');
</script>

Sending Pageviews Yourself

With autoPageView: false, call dotEvents.pageView() on each page, optionally with your own data. Call it as well when the browser brings back a page the visitor returns to with the Back button, which it can do without loading it again:

dotEvents.pageView({ campaign: 'spring' });

window.addEventListener('pageshow', (event) => {
    if (event.persisted) {
        dotEvents.pageView();
    }
});

SDK Reference

dotEvents and the types it uses are imported from @dotcms/events. The two pieces that print what a page needs to run its experiment have their own entries: DotCMSExperiment from @dotcms/events/react, and experimentMarkup from @dotcms/events/markup.

dotEvents

dotEvents is the object every entry point shares. There is one per page: every import gets the same instance, configured by the one init call, and it carries the three methods below.

Every method does nothing on the server and inside the Universal Visual Editor, and none of them throws: failures reach your page through onError.

dotEvents.init(config)

dotEvents.init is the function that starts the SDK. Call it once, as early as possible: in Next.js that is src/instrumentation-client.ts, and in any other app wherever it starts, before it renders.

| Input | Type | Required | Description | | -------- | -------------------- | -------- | ------------------------------------------- | | config | DotCMSEventsConfig | ✅ | The SDK's configuration |

Usage

import { dotEvents } from '@dotcms/events';

dotEvents.init({
    dotcmsUrl: process.env.NEXT_PUBLIC_DOTCMS_HOST!,
    siteAuth: process.env.NEXT_PUBLIC_DOTCMS_SITE_AUTH!,
    impressions: true,
    clicks: true
});

What a Second Call Does

  • The same configuration: the second call does nothing.
  • Another configuration: ignored, with a console warning.
  • dotcmsUrl or siteAuth missing: nothing starts, and a console error says which one.
  • conversion or pageView called before init finishes: the call waits and runs once the SDK is ready, up to 50 waiting calls.
  • Inside the Universal Visual Editor: nothing is tracked, and experiment content is shown as it is.

dotEvents.conversion(name)

dotEvents.conversion is the function that records a conversion. dotCMS records the name and the page; its schema accepts no other data, so a conversion carries no custom properties.

| Input | Type | Required | Description | | ------ | -------- | -------- | ------------------------------------------------------- | | name | string | ✅ | The conversion's name. An empty name is ignored with a console warning |

Call it only once the goal is reached — a completed purchase, a finished download, a created account — never on the click that started it.

Usage

'use client';

import { dotEvents } from '@dotcms/events';

export function SignupForm() {
    const onSubmit = async (event: React.FormEvent) => {
        event.preventDefault();
        await createAccount(); // your own code

        dotEvents.conversion('signup');
    };

    return <form onSubmit={onSubmit}>{/* fields */}</form>;
}

dotEvents.pageView(data?)

dotEvents.pageView is the function that sends a pageview by hand. Only needed with autoPageView: false.

| Input | Type | Required | Description | | ------ | ------------------------ | -------- | ------------------------------------------------------------------ | | data | DotCMSEventsJsonObject | ❌ | Your own data, which arrives in the event's data.custom |

On a page that runs an experiment, the pageview waits for the visitor's variant, and is dropped if the SDK sends the visitor to another variant: that page sends its own.

Usage

dotEvents.pageView({ campaign: 'spring' });

// A page the browser brings back with the Back button is seen again, without loading again
window.addEventListener('pageshow', (event) => {
    if (event.persisted) {
        dotEvents.pageView();
    }
});

DotCMSExperiment

DotCMSExperiment is a component that runs the page's experiment on the content it wraps. On a page that runs an experiment it wraps children in an element marked with the experiment and the variant the server rendered, keeps it hidden, and prints the script that decides the visitor's variant while the HTML is parsed. On a page that runs none it renders children alone, so every page can be wrapped the same way.

| Input | Type | Required | Default | Description | | ----------- | ---------------------------- | -------- | ------- | ------------------------------------------------------------- | | page | DotCMSEventsExperimentPage | ✅ | - | The page asset, requested with the URL's variantName | | children | ReactNode | ✅ | - | What the experiment changes: the page's layout, or part of it | | nonce | string | ❌ | - | The nonce of a nonce-based Content-Security-Policy | | className | string | ❌ | - | A class for the element that wraps the content |

It uses no hooks, so it also renders in a server component — where it adds no JavaScript to the browser. In a client component it adds about 1.5 KB.

Usage

// src/app/[[...slug]]/page.tsx
import { DotCMSExperiment } from '@dotcms/events/react';

export default async function Page({ params, searchParams }: PageProps) {
    const { slug } = await params;
    const { variantName } = await searchParams;
    const path = slug?.length ? `/${slug.join('/')}` : '/';

    // variantName makes dotCMS render the visitor's variant
    const pageContent = await dotCMSClient.page.get(path, { variantName });

    return (
        <DotCMSExperiment page={pageContent.pageAsset}>
            <DotCMSLayoutBody page={pageContent.pageAsset} components={pageComponents} />
        </DotCMSExperiment>
    );
}

experimentMarkup(page)

experimentMarkup is the function that returns what a server-rendered page prints to run its experiment, for frameworks other than React. It returns null when the page runs no experiment.

| Input | Type | Required | Description | | ------ | ---------------------------- | -------- | ------------------------------------------------------------- | | page | DotCMSEventsExperimentPage | ✅ | The page asset, requested with the URL's variantName |

Usage

import { experimentMarkup } from '@dotcms/events/markup';

const markup = experimentMarkup(pageAsset); // null when the page runs no experiment

// <style>{markup.style}</style>
// <script>{markup.script}</script>
// <div {...markup.attributes}>the content the experiment changes</div>

style is the rule that keeps the marked element hidden until the variant is decided, script is the boot script's source, and attributes are data-dot-experiment and data-dot-variant for the element that wraps what the experiment varies.

The style and the script must come before that element in the HTML the server sends: the script decides the visitor's variant while that HTML is parsed.

window.dotEvents

After init, the same object is on window, so a plain script on the page reaches it without a bundler.

Usage

<script>
    window.dotEvents?.conversion('newsletter');
</script>

Migrating from @dotcms/analytics and @dotcms/experiments

| Before | With @dotcms/events | | ------------------------------------------------------------- | ------------------------------------------------------------------------------- | | <DotContentAnalytics config={...} /> in the root layout | dotEvents.init({...}) in src/instrumentation-client.ts | | server in the analytics config | dotcmsUrl | | useContentAnalytics(config).conversion(name, data) | dotEvents.conversion(name): dotCMS records the name only | | useContentAnalytics(config).pageView(data) | dotEvents.pageView(data), with autoPageView: false | | useContentAnalytics(config).track(name, data) | Not available: dotCMS accepts pageviews, conversions, impressions and clicks only | | withExperiments(DotCMSLayoutBody, config) | <DotCMSExperiment page={pageAsset}> around the content | | A separate experiments config, with its own key | The same init call: experiments are on by default |

Visitor and session ids are stored under new names (dot_events_*), so visitors start with new ids after the switch.

Under the Hood

What It Stores

No cookies. Everything carries the dot_events_ prefix:

| Key | Storage | Contents | | ---------------------------------- | -------------- | ------------------------------------------------------------ | | dot_events_user_id | localStorage | The visitor's anonymous id | | dot_events_experiments | localStorage | The visitor's experiment assignments | | dot_events_experiments_off_until | localStorage | Set when experiments are off for the site, for a day | | dot_events_session_id | sessionStorage | The session's id | | dot_events_tab_id | sessionStorage | The tab's id | | dot_events_queue_<tab id> | sessionStorage | Events not sent yet, kept until the next page sends them | | dot_events_experiments_checked | sessionStorage | This tab already asked for the visitor's assignments | | dot_events_session_experiments | sessionStorage | The experiments the visitor joined during the session |

What It Sends

Every event carries, besides its own data:

  • The site's Site Auth, so dotCMS knows which site it belongs to
  • The visitor's anonymous id and the session's id
  • The visitor's screen resolution, viewport size and language
  • The experiments the visitor joined in the session, on pages running an experiment they are in

It sends nothing else about the visitor, and no cookies. The four event types — pageview, conversion, content_impression and content_click — are the only ones dotCMS accepts; there is no custom-event API.

Endpoints

| Request | What for | | ------------------------------------------ | ----------------------------------------- | | POST {dotcmsUrl}/api/v1/analytics/content/event | Every event | | POST {dotcmsUrl}/api/v1/experiments/isUserIncluded | The visitor's experiment assignments |

Troubleshooting

Common Issues & Solutions

| Symptom | Likely cause | What to do | | ------------------------------------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- | | No events in the Network tab | Missing dotcmsUrl or siteAuth, or you're inside the Universal Visual Editor | Check both values, test outside the editor, and turn on debug: true | | Environment variables are empty | Next.js only exposes variables that start with NEXT_PUBLIC_ to the browser | Rename them, and restart the dev server after changing .env.local | | onError reports REJECTED | dotCMS refused the events | Check that siteAuth is the Site Auth of the same site, and read detail | | No impressions | impressions is off, the contentlets lack dotCMS's attributes, or the tab is hidden | Turn it on, render with a dotCMS SDK, and keep the page in view while testing | | No clicks | clicks is off, or the element isn't a link or button inside a contentlet | Turn it on, and click a link or button inside a contentlet | | The variant never shows | The route doesn't pass variantName to the page request, or the page is built ahead of time | Pass variantName, and render the page on every request | | The page reloads once on a first visit | Expected: the visitor is being sent to their variant | Nothing to do | | The experiment content appears after 3 seconds | dotCMS took longer than 3 seconds to answer | The original shows; the visitor gets their variant from the next page on | | Nothing about experiments in the Network tab | The experiment isn't running in dotCMS, or experiments are off | Check the experiment's status in dotCMS, and look for EXPERIMENTS in onError |

Debugging Tips

  1. Turn on debug mode. debug: true logs what the SDK does to the browser console, and warns about setup mistakes, such as a route that ignores variantName.
  2. Watch the Network tab. Filter by /api/v1/analytics/content/event to see each batch of events, and by isUserIncluded to see the experiments check.
  3. Check the storage. In DevTools > Application, look for the dot_events_* keys in localStorage and sessionStorage. Clearing them makes you a new visitor, with a new experiment assignment.

Still Having Issues?

If you're still experiencing problems after trying these solutions:

  1. Search existing GitHub issues
  2. Ask questions on the community forum to engage with other users.
  3. Create a new issue with:
    • Detailed reproduction steps
    • Environment information
    • Error messages
    • Code samples

Support

We offer multiple channels to get help with the dotCMS Events SDK:

  • GitHub Issues: For bug reports and feature requests, please open an issue in the GitHub repository.
  • Community Forum: Join our community discussions to ask questions and share solutions.
  • Stack Overflow: Use the tag dotcms-events when posting questions.
  • Enterprise Support: Enterprise customers can access premium support through the dotCMS Support Portal.

When reporting issues, please include:

  • SDK version you're using
  • Framework/library version (if applicable)
  • Minimal reproduction steps
  • Expected vs. actual behavior

Contributing

GitHub pull requests are the preferred method to contribute code to dotCMS. We welcome contributions to the dotCMS Events SDK! If you'd like to contribute, please follow these steps:

  1. Fork the repository dotCMS/core
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Please ensure your code follows the existing style and includes appropriate tests.

Licensing

dotCMS is available under either the Business Source License 1.1 (BSL) or a commercial license.

Under the BSL, dotCMS can be used at no cost by individual developers, small businesses or agencies under $5M in total finances, and by larger organizations in non-production environments. Every BSL release automatically converts to GPL v3 four years after its release date. For full terms and FAQs, visit dotcms.com/bsl and dotcms.com/bsl-faq.

Production use in larger organizations, along with access to managed cloud, SLAs, support, and enterprise capabilities, is available under a commercial license from dotCMS. For details on commercial plans, features, and support options, see dotcms.com/pricing.