@dotcms/experiments 1.0.0: Next.js 15 App Router integration crashes in UVE editor, spurious /api/v1/experiments/DEFAULT 404, and stale npm docs
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 970
- Forks
- 486
- Avg merge
- 3d 33m
- Merged PRs (30d)
- 170
Description
Problem Statement
A customer integrating A/B testing with @dotcms/experiments@1.0.0 in a Next.js 15 (App Router) app (with @dotcms/react, @dotcms/uve, Analytics enabled) hit several issues. Investigation of core-web/libs/sdk/experiments/src/ confirms the SDK behavior and points to concrete defects on our side.
Confirmed findings (from source):
-
Stale npm/docs vs. actual API. The npm docs reference
import { DotExperimentsProvider } from "@dotcms/experiments", butcore-web/libs/sdk/experiments/src/index.tsonly exportswithExperiments.DotExperimentsProvideris internal. The customer's use ofwithExperimentsis the correct, supported pattern. -
UVE/editor crash ("A client-side exception has occurred"). The SDK does implement editor detection (
getUVEState()?.modeinDotExperimentsProvider.tsxanduseExperiments.ts;UVE_MODE.EDITinuseExperimentVariant.ts). Two root-cause candidates:withExperimentsis itself a hook (callsuseMemoizedObject+useCallback, with/* eslint-disable react-hooks/rules-of-hooks */inwithExperiments.tsx). The README's recommended conditional patternapiKey ? withExperiments(...) : DotCMSLayoutBodycalls a hook conditionally — a rules-of-hooks violation that can crash, and differs between editor/published render paths.- If the UVE integration layer is not mounted,
getUVEState()returnsundefined, theif (!insideEditor)guard passes, and the SDK initializes inside the editor without atry/catchsafety net.
-
GET /api/v1/experiments/DEFAULT→ 404. The SDK only ever callsapi/v1/experiments/isUserIncluded(API_EXPERIMENTS_URLinconstants.ts). The/DEFAULTrequest comes from the Angular backoffice:DotExperimentsService.getById()incore-web/libs/data-access/src/lib/dot-experiments/dot-experiments.service.tsissuesGET /api/v1/experiments/${experimentId}. When the default variant name"DEFAULT"(EXPERIMENT_DEFAULT_VARIANT_NAME) is passed as an experiment ID, the call 404s. -
"No experiments assigned to the client." Expected when the experiment is not in
Runningstatus or no analytics session exists yet — needs confirmation against the customer's experiment state. -
No working Next.js 15 reference.
examples/nextjsdeclares@dotcms/experimentsinpackage.jsonbut never useswithExperimentsand does not document the integration, so there is no canonical example to point customers to.
Impact: Blocks a business-critical A/B test on the Lennox Commercial homepage. Priority/severity High.
Environment: Next.js 15 (App Router), @dotcms/experiments@1.0.0, @dotcms/react, @dotcms/uve, dotCMS QA (Current Release / dotEvergreen). Browser: Chrome.
Steps to Reproduce
- Build a Next.js 15 (App Router) app using
@dotcms/react+@dotcms/uve. - Wrap
DotCMSLayoutBodywithwithExperimentsusing the conditional pattern from the README:apiKey ? withExperiments(DotCMSLayoutBody, { apiKey, server, redirectFn }) : DotCMSLayoutBody. - Configure an experiment on a page (variant name e.g.
HomeNew) with DEFAULT + custom variants. - Open the page inside the dotCMS UVE/backoffice editor → page fails to load: "A client-side exception has occurred."
- Observe the browser console:
GET /api/v1/experiments/DEFAULT 404 (Not Found)andNo experiments assigned to the client.
Acceptance Criteria
-
@dotcms/experimentsREADME, npm docs, and theDotExperimentsProvider.tsxJSDoc accurately state thatwithExperimentsis the only public export; remove/replaceDotExperimentsProviderusage examples. - The recommended integration pattern does not violate the rules of hooks.
withExperiments(or the documented usage) handles the "no apiKey" case without conditionally calling a hook, so toggling experiments on/off cannot crash. - Opening a page inside the UVE editor never crashes due to experiments, including when
getUVEState()returnsundefined/null. Experiment initialization is skipped in editor mode and any init error is caught and logged rather than thrown. - Root cause of
GET /api/v1/experiments/DEFAULT404 is identified and fixed:DotExperimentsService.getById()(and its caller) no longer requests an experiment using the default variant name"DEFAULT"as an ID; invalid/empty IDs short-circuit instead of hitting the API. -
examples/nextjsincludes a complete, workingwithExperimentsintegration (wrappingDotCMSLayoutBodyinsrc/views/Page.jswith the safe pattern) and the README documents the Next.js 15 App Router setup. - Documentation clarifies the
serverconfig must point directly to the dotCMS origin (not Azure Front Door/CDN), since experiment API responses are session-specific and must not be cached. - Existing SDK specs (
DotExperimentsProvider.spec.tsx,useExperimentVariant.spec.tsx) pass and cover the editor-mode no-crash path.
dotCMS Version
Current Release / dotEvergreen (QA). @dotcms/experiments@1.0.0, Next.js 15 (App Router), @dotcms/react, @dotcms/uve.
Severity
High - Major functionality broken
Links
- Freshdesk ticket #37931
- Affected site: www.lennoxcommercial.com (index page), variant name
HomeNew
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with core-web/libs/sdk/experiments/src/withExperiments.tsx, DotExperimentsProvider.tsx, useExperiments.ts, useExperimentVariant.ts, and constants.ts, then inspect DotExperimentsService in core-web/libs/data-access/src/lib/dot-experiments/dot-experiments.service.ts. Review examples/nextjs/src/views/Page.js and its README for the integration pattern. Done means the documented integration is safe in UVE, the DEFAULT request is avoided, docs are accurate, and DotExperimentsProvider.spec.tsx and useExperimentVariant.spec.tsx cover the editor path.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- angular, next.js, react, typescript
- Domain
- api, documentation, frontend, testing, web-dev
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 28/100