UVE: Restore `What's Changed` (live vs working diff) on VTL Pages
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 970
- Forks
- 486
- Avg merge
- 3d 33m
- Merged PRs (30d)
- 170
Description
Description
The What's Changed feature — a live vs. working diff of a page — is no longer reachable from the Universal Visual Editor. Customers are asking for it back (Freshdesk #39003).
The removal was collateral, not a product decision. The feature's UI lived inside the legacy Edit Page portlet and was deleted wholesale in PR #34385 (commit 26bb7f3775, 2026-01-26, "chore: Remove legacy Edit Page Portlet from codebase").
The entire pipeline is still in the codebase and still maintained
| Layer | Location | State |
|---|---|---|
| Renderer | HTMLPageAssetRenderedAPIImpl.getPageRenderedLivePreviewVersion() — HTMLPageAssetRenderedAPIImpl.java:652 |
✅ Intact |
| Response bean | PageLivePreviewVersionBean (renderLive, renderWorking, diff) |
✅ Intact |
| REST endpoint | GET /api/v1/page/{pageId}/render/versions?langId= — PageResource.java:1337 |
✅ Intact, Swagger-documented as getPageRenderVersions |
| Angular service | DotEditPageService.whatChange(pageId, languageId) |
✅ Intact — zero callers |
| Model | DotWhatChanged — libs/dotcms-models/src/lib/dot-what-changed.model.ts |
✅ Intact |
| Diff renderer | DotDiffPipe (htmldiff-js) — libs/ui/src/lib/pipes/dot-diff/ |
✅ Intact |
The backend is not stale: commit 9c0834db27 (2026-03-23) added UVE script-block stripping so the comparison is purely on page content.
What was actually deleted
dot-whats-changed.component.ts/.html/.scss— the iframe host that wrote the diff HTML viadocument.writedot-edit-page-state-controlleranddot-edit-page-toolbar— where the checkbox lived- The
SHOW_DIFF_STYLESconstant —del { text-decoration: line-through; background-color: #fdb8c0 } ins { text-decoration: underline; background-color: #ddffdd }
No backend work is required. This is a frontend-only restore.
Acceptance Criteria
Happy path
- A "What's Changed" toggle is present in the UVE toolbar, alongside the Edit / Preview / Live controls.
- Enabling the toggle calls
DotEditPageService.whatChange(pageId, languageId)with the page's current identifier and language. - The returned
renderLiveandrenderWorkingare passed throughDotDiffPipeand the resulting HTML replaces the content of the existing UVE preview iframe. - Diff highlight styles are injected into the iframe document: removed content renders struck-through on red, added content renders underlined on green.
- Disabling the toggle restores the normal UVE render without requiring a page reload.
- Switching language while the toggle is on re-fetches the diff for the newly selected language.
Sad path
- When the response returns
diff: false, an empty state is shown instead of an iframe — reusing the existingnothing-changedmessage key. - A
403from the endpoint (user lacksEDITpermission on the page) is routed throughDotHttpErrorManagerServiceand does not leave the toggle stuck in a loading state. - Any other HTTP error surfaces via
DotHttpErrorManagerServiceand the toggle reverts to off.
Edge cases
- Navigating to a different page with the toggle on re-fetches the diff for the new page.
- The toggle is not available for headless/SPA pages, since the endpoint returns dotCMS-rendered HTML (see Additional Context).
- Unit tests cover: toggle on/off,
diff: falseempty state, error handling, and language change.
Priority
Medium
Additional Context
Scope decisions for this issue
- Traditional (VTL) pages only. The endpoint renders through
HTMLPageAssetRenderedBuilderand returns dotCMS-rendered HTML — it produces nothing meaningful for headless/SPA pages. - Render surface: reuse the existing UVE iframe. Closest to the original behavior and lowest effort; the diff HTML is written into the same iframe rather than a new mode or a side-by-side panel.
Known gaps — follow-up work, explicitly out of scope here
- Headless / SPA support. This is the real open design question and needs its own issue. The current endpoint cannot serve it without new backend work.
- The
diffflag is a naive string equals.PageLivePreviewVersionBeancomputesdiff = !renderLive.equals(renderWorking). Insignificant markup differences will report as changed. - UI polish. The original checkbox UX was called out as needing improvement; a richer presentation (side-by-side, change navigation) is deferred.
Constraints
- The endpoint throws
DotSecurityExceptionunless the user hasPERMISSION_EDITon the page — the toggle should account for this. DotDiffPipestripsdata="…"attributes before diffing, becausehtmldiff-jsbreaks on them.
References
- Freshdesk ticket: https://dotcms.freshdesk.com/a/tickets/39003
- Removal commit:
26bb7f3775(PR #34385) - Prior art to restore from:
git show 26bb7f3775^:core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/content/components/dot-whats-changed/dot-whats-changed.component.ts
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 the prior implementation at core-web/apps/dotcms-ui/src/app/portlets/dot-edit-page/content/components/dot-whats-changed/dot-whats-changed.component.ts, then trace the existing UVE toolbar, DotEditPageService.whatChange, DotDiffPipe, and preview iframe. Restore the toggle for traditional VTL pages, including empty and error states, language/page changes, and unit tests covering the listed behaviors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- angular, typescript
- Domain
- frontend, testing-qa
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100