Description
The one place where the new flow overlaps something customers use today is the experiments entry point inside the Universal Visual Editor. This issue (a) completes the Variants card of #37003 with the Edit Content round-trip into UVE, and (b) switches the UVE entry point to the new portlet flow behind a feature flag, off by default — the old per-page screens keep working unchanged in every build until the flag is flipped, and it can be flipped back.
This is the only issue before the migration that modifies existing behavior.
1. Variant Edit Content round-trip
Edit Content on a variant navigates to UVE for {pageId, variantName} using the existing deep-link shape: /edit-page/content?url=…&variantName=…&experimentId=… (current construction: dot-uve-toolbar.component.ts:262-277).
- Build the URL from the experiment's page data in the store — do not copy the current
getUrl() that parses window.location.href (dot-experiments-configuration-variants.component.ts:187-234).
- Returning from UVE lands back in the portlet, on
/experiments/:id/configuration for the experiment the editor came from — resolved by experiment identity, not by page, since a page can host more than one experiment.
- Control variant and locked experiments open UVE read-only (
Preview), per the design.
- No "edited" indicator. No edited/revision signal exists on the variant model on either side of the wire (
AbstractExperimentVariant, Variant), and the legacy per-page Variants card shows no edit indication at all. Do not invent one — not persisted, not derived, not session-held. The deliverable is the correct round-trip, not a badge.
- One consequence: the new Variants card renders the fixed string
No content changes yet for every non-control variant (experiments.configure.variants.meta.variant). That is true today only because the Edit Content button beside it is disabled. This issue is what makes it capable of being false, so the string must be reworded to something state-neutral or dropped.
2. UVE entry-point switch behind the flag
The flag. Add a new, dedicated flag — FEATURE_FLAG_EXPERIMENTS_PORTLET — shipped explicitly false in dotmarketing-config.properties, with a matching FeaturedFlags entry and an allow-list entry in ConfigurationResource so the frontend can read it.
- Do not reuse
FEATURE_FLAG_EXPERIMENTS. It is already read by ConfigExperimentUtil.isExperimentEnabled() and gates experiment JS injection (ExperimentWebAPIImpl:338) and experiment resolution during page render (HTMLPageAssetRenderedAPIImpl:176,239). Setting it to false — this issue's intended default — would take running experiments off the air. It keeps its current name, meaning, default and consumers; this work does not touch it.
- The explicit
false is required, not optional: DotPropertiesService.getFeatureFlags() and withFlags() both map an absent flag (NOT_FOUND) to enabled. A flag that is merely declared ships on.
- The unused frontend enum entry
FeaturedFlags.LOAD_FRONTEND_EXPERIMENTS = 'FEATURE_FLAG_EXPERIMENTS' (libs/dotcms-models/src/lib/shared-models.ts:28) gains no consumer under this decision and can be deleted in the migration — the property must survive.
Behavior.
- Flag on: the UVE experiments nav item routes to the portlet's site-wide list, filtered to the page in hand — not an unfiltered list, and not straight to a single experiment. Must behave for zero (empty state scoped to the page, with a way to create one), one, and many experiments; the filter is visible and clearable.
- Flag off (default): byte-identical behavior to today — nav item, per-page list, deep-links.
- Mechanism:
withFlags([...]) / DotPropertiesService.getFeatureFlags(); precedent: FEATURE_FLAG_EDIT_CONTENT_SIDE_PANEL in dot-content-drive and edit-ema.
Must not break (flag off)
The UVE nav item (dot-ema-shell.component.ts:143-149), the toolbar deep-links (dot-ema-running-experiment.component.html:2-7, dot-uve-toolbar.component.ts:262-277), and the nav-href spec dot-ema-shell.component.spec.ts:117-120.
Acceptance Criteria
Priority
Medium.
Additional Context
Description
The one place where the new flow overlaps something customers use today is the experiments entry point inside the Universal Visual Editor. This issue (a) completes the Variants card of #37003 with the Edit Content round-trip into UVE, and (b) switches the UVE entry point to the new portlet flow behind a feature flag, off by default — the old per-page screens keep working unchanged in every build until the flag is flipped, and it can be flipped back.
This is the only issue before the migration that modifies existing behavior.
1. Variant Edit Content round-trip
Edit Contenton a variant navigates to UVE for{pageId, variantName}using the existing deep-link shape:/edit-page/content?url=…&variantName=…&experimentId=…(current construction:dot-uve-toolbar.component.ts:262-277).getUrl()that parseswindow.location.href(dot-experiments-configuration-variants.component.ts:187-234)./experiments/:id/configurationfor the experiment the editor came from — resolved by experiment identity, not by page, since a page can host more than one experiment.Preview), per the design.AbstractExperimentVariant,Variant), and the legacy per-page Variants card shows no edit indication at all. Do not invent one — not persisted, not derived, not session-held. The deliverable is the correct round-trip, not a badge.No content changes yetfor every non-control variant (experiments.configure.variants.meta.variant). That is true today only because the Edit Content button beside it is disabled. This issue is what makes it capable of being false, so the string must be reworded to something state-neutral or dropped.2. UVE entry-point switch behind the flag
The flag. Add a new, dedicated flag —
FEATURE_FLAG_EXPERIMENTS_PORTLET— shipped explicitlyfalseindotmarketing-config.properties, with a matchingFeaturedFlagsentry and an allow-list entry inConfigurationResourceso the frontend can read it.FEATURE_FLAG_EXPERIMENTS. It is already read byConfigExperimentUtil.isExperimentEnabled()and gates experiment JS injection (ExperimentWebAPIImpl:338) and experiment resolution during page render (HTMLPageAssetRenderedAPIImpl:176,239). Setting it tofalse— this issue's intended default — would take running experiments off the air. It keeps its current name, meaning, default and consumers; this work does not touch it.falseis required, not optional:DotPropertiesService.getFeatureFlags()andwithFlags()both map an absent flag (NOT_FOUND) to enabled. A flag that is merely declared ships on.FeaturedFlags.LOAD_FRONTEND_EXPERIMENTS = 'FEATURE_FLAG_EXPERIMENTS'(libs/dotcms-models/src/lib/shared-models.ts:28) gains no consumer under this decision and can be deleted in the migration — the property must survive.Behavior.
withFlags([...])/DotPropertiesService.getFeatureFlags(); precedent:FEATURE_FLAG_EDIT_CONTENT_SIDE_PANELindot-content-driveandedit-ema.Must not break (flag off)
The UVE nav item (
dot-ema-shell.component.ts:143-149), the toolbar deep-links (dot-ema-running-experiment.component.html:2-7,dot-uve-toolbar.component.ts:262-277), and the nav-href specdot-ema-shell.component.spec.ts:117-120.Acceptance Criteria
FEATURE_FLAG_EXPERIMENTSis untouched by this work.Edit Contenton a non-control variant opens UVE for that variant; Save/back returns to/experiments/:id/configurationfor the originating experiment, including on a page with more than one experiment.window.location.hrefparsing — the deep-link is built from store data.Priority
Medium.
Additional Context
specs/37005-experiments-uve-integration/spec.md(D1/D2/D3 record the three corrections and why).FEATURE_FLAG_EXPERIMENTS_PORTLET, notFEATURE_FLAG_EXPERIMENTS— the latter gates visitor-facing experiment delivery and must survive. The unusedLOAD_FRONTEND_EXPERIMENTSenum entry can be dropped there.