-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Preview: Fix preview showing published version when Save and Preview is clicked multiple times (closes #20981) #20992
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Preview: Fix preview showing published version when Save and Preview is clicked multiple times (closes #20981) #20992
Conversation
…d multiple times Fixes #20981 When clicking "Save and Preview" multiple times, the preview tab would show the published version instead of the latest saved version. This occurred because: 1. Each "Save and Preview" creates a new preview session with a new token 2. The preview window is reused (via named window target) 3. Without a URL change, the browser doesn't reload and misses the new session token 4. The stale page gets redirected to the published URL Solution: Add a cache-busting parameter (?rnd=timestamp) to the preview URL, forcing the browser to reload and pick up the new preview session token. This aligns with how SignalR refreshes work. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
…lready open When clicking "Save and Preview" multiple times with a preview tab already open, the entire preview tab would reload. This enhancement makes it behave like the "Save" button - only the iframe reloads, not the entire preview wrapper. Changes: - Store reference to preview window when opened - Check if preview window is still open before creating new session - If open, just focus it and let SignalR handle the iframe refresh - If closed, create new preview session and open new window This provides a smoother UX where subsequent saves don't cause the preview frame and controls to reload, only the content iframe refreshes via SignalR. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Changes the "End Preview" behavior to close the preview tab instead of navigating to the published URL. This provides a cleaner UX and ensures subsequent "Save and Preview" actions will always create a fresh preview session. Benefits: - Eliminates edge case where preview window remains open but is no longer in preview mode - Simpler behavior - preview session ends and window closes - Users can use "Preview website" button if they want to view published page Also removes unnecessary await on SignalR connection.stop() to prevent blocking if the connection cleanup hangs. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit addresses cookie management issues in the preview system: 1. **Cookie Expiration API Enhancement** - Added `ExpireCookie` overload with security parameters (httpOnly, secure, sameSiteMode) - Added `SetCookieValue` overload with optional expires parameter - Marked old methods as obsolete for removal in Umbraco 19 - Ensures cookies are expired with matching security attributes 2. **PreviewService Cookie Handling** - Changed to use new `ExpireCookie` method with explicit security attributes - Maintains `Secure=true` and `SameSite=None` for cross-site scenarios - Uses new `SetCookieValue` overload with explicit expires parameter - Properly expires preview cookies when ending preview session 3. **Frontend Error Handling** - Added try-catch around preview window reference checks - Handles stale window references gracefully - Prevents potential errors from accessing closed window properties These changes ensure preview cookies are properly managed throughout their lifecycle and support both same-site and cross-site scenarios (e.g., when the backoffice is on a different domain/port during development). Fixes #20981 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
… different documents When navigating from one document to another in the backoffice, the preview window reference was being reused even though it was showing a different document. This meant clicking "Save and Preview" would just focus the existing window without updating it to show the new document. Now we track which document the preview window is showing and only reuse the window if: 1. The window is still open 2. The window is showing the same document This ensures each document gets its own preview session while still avoiding unnecessary full page reloads when repeatedly previewing the same document. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes a preview issue (#20981) where clicking "Save and Preview" multiple times would show the published version instead of the latest saved changes. The root cause was that each "Save and Preview" action created a new preview session, invalidating the cookie in the already-open preview tab.
Key changes:
- Implemented preview window reference tracking to reuse existing windows when previewing the same document
- Added cache-busting to preview URLs to force browser reloads when creating new preview sessions
- Updated preview exit behavior to close the window instead of navigating away
- Enhanced cookie management API to properly expire cookies with matching security attributes
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/Umbraco.Web.UI.Client/src/packages/documents/documents/workspace/document-workspace.context.ts | Adds window reference tracking (#previewWindow, #previewWindowDocumentId) to reuse existing preview windows for the same document and avoid unnecessary preview session creation; adds cache-busting to preview URLs |
| src/Umbraco.Web.UI.Client/src/packages/preview/preview-apps/preview-environments.element.ts | Adds cache-busting to preview environment URLs to ensure preview tabs reload with new session tokens |
| src/Umbraco.Web.UI.Client/src/packages/preview/context/preview.context.ts | Changes "End Preview" behavior to close the window instead of navigating to published URL, ensuring clean session lifecycle; removes await on SignalR connection stop for faster cleanup |
| src/Umbraco.Core/Web/ICookieManager.cs | Adds new overloads for ExpireCookie and SetCookieValue that accept security attributes and expiration dates; marks old methods as obsolete |
| src/Umbraco.Web.Common/AspNetCore/AspNetCoreCookieManager.cs | Implements new cookie management overloads with proper security attribute handling |
| src/Umbraco.Core/Services/PreviewService.cs | Updates preview cookie creation and expiration to use proper security attributes (SameSite=None, Secure=true, HttpOnly=true) for cross-site scenarios |
AndyButland
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've fixed the issue with the preview path we were discussing, and simplified the cookie expiry to use .Delete, which meant we then didn't need the overloads. Preview looks to work as expected now. Happy to approve but I'll just leave you to look over next week just to be sure I didn't break anything in my updates or missing anything you were looking to do.
|
I tested it out, and it works, @AndyButland, so great find on the .Delete method. We could think of adding the CookieSecurePolicy to make cookies work the same throughout the app, but I don't think that is a strict requirement at the moment given that Preview mode seems to have always required Secure cookies (= only works on https). options.Cookie.SecurePolicy =
_globalSettings.UseHttps ? CookieSecurePolicy.Always : CookieSecurePolicy.SameAsRequestI'll wait for @leekelleher to test out the Backoffice functionality and see if preview mode has improved, too :-) |
leekelleher
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested out, works as described. 🚀
Summary
Fixes an issue where clicking "Save and Preview" multiple times causes the preview tab to show the published version instead of the latest saved version. This PR addresses the root cause: new preview sessions were being created on each "Save and Preview" action, invalidating the preview cookie in the already-open preview tab.
Changes
1. Cache-busting for preview URLs
Added a
?rnd=timestampparameter to preview URLs to ensure the browser reloads the page with the new preview session token, even when the preview window is reused.Files changed:
2. Preview window reference tracking
Store a reference to the preview window to avoid creating unnecessary new preview sessions. When the preview window is still open and showing the same document, we simply focus it and let SignalR handle the content refresh.
Files changed:
3. Document-specific preview window tracking
Track which document the preview window is showing to ensure each document gets its own preview session. This prevents reusing a preview window when navigating between different documents in the backoffice.
Files changed:
4. Close preview window when ending session
Modified the "End Preview" action to close the preview window instead of navigating away. This ensures that subsequent "Save and Preview" actions create a new session rather than attempting to reuse a tab that's no longer in preview mode.
Files changed:
5. Fix preview cookie expiration
Added proper cookie expiration methods that match the security attributes used when creating preview cookies. This fixes an issue where clicking "Preview website" would still show the preview overlay because the preview cookie wasn't being properly removed.
Files changed:
expiresparameterSecure=true,SameSite=None,HttpOnly=true)The preview cookies now use
SameSite=NoneandSecure=trueto support cross-site scenarios (e.g., when the backoffice is on a different domain/port than the frontend during development).SameSite=NonerequiresSecure=trueper browser specifications.How this fixes issue #20981
The original issue occurred because:
This PR fixes it by:
Test steps
Test 1: Original issue - Same document, multiple saves
Expected: Preview shows the latest saved version
Previously: Preview showed the published version ❌
Test 2: Different documents
Expected: Preview shows Document B
Previously: Preview would just focus without changing content ❌
Test 3: End preview session
Expected: Clean session lifecycle
Previously: Preview tab would stay open causing issues ❌
Test 4: Preview website
Expected: No preview overlay on published site
Previously: Preview overlay would appear on published site ❌
Test 5: Cross-site scenario
Expected: Preview cookies work in cross-site scenarios
Breaking changes
None. New method overloads were added with obsolete attributes on old methods to maintain backwards compatibility. Old methods will be removed in Umbraco 19.
🤖 Generated with Claude Code
Co-Authored-By: Claude noreply@anthropic.com