Skip to content

fix: resolve Page Builder hydration mismatch in SliceSimulator#131

Open
angeloashmore wants to merge 3 commits into
mainfrom
aa/simplify-slice-simulator
Open

fix: resolve Page Builder hydration mismatch in SliceSimulator#131
angeloashmore wants to merge 3 commits into
mainfrom
aa/simplify-slice-simulator

Conversation

@angeloashmore

@angeloashmore angeloashmore commented Feb 24, 2026

Copy link
Copy Markdown
Member

Resolves: prismicio/slice-machine#1768

Description

The App Router version of <SliceSimulator> has a typeof window === undefined check to conditionally read the simulator URL's state param; if rendered on the server, we don't read the parameter. The check is part of the component's render cycle, not in a useEffect.

This kind of check can lead to a React hydration error where the server renders as if there is no state param and the client renders using the actual state param value. The mismatch can throw an error.

This PR simplifies <SliceSimulator> to ignore window altogether. The change simplifies <SliceSimulator and the underlying code and eliminates a possible bug.

Checklist

  • A comprehensive Linear ticket, providing sufficient context and details to facilitate the review of the PR, is linked to the PR.
  • If my changes require tests, I added them.
  • If my changes affect backward compatibility, it has been discussed.
  • If my changes require an update to the CONTRIBUTING.md guide, I updated it.

Preview

How to QA 1

  1. Deploy a Next.js App Router project with Prismic to Vercel
  2. Open Prismic Page Builder and select a slice to preview
  3. Make repeated content modifications (text changes, adding/removing slices)
  4. Verify the preview updates smoothly without iframe refreshes or React errors

Note

Low Risk
Client-only behavior is simplified and event subscriptions are stabilized; main risk is subtle changes in simulator rendering when no slices/message are present.

Overview
Removes URL state parsing from the App Router SliceSimulator render path (dropping getSlices/hasSlices) to prevent server/client hydration mismatches.

Stabilizes the StateEventType.Slices handler by using a routerRef and an empty-effect dependency array, and simplifies SliceSimulatorWrapper to always render the simulator root when no message is present (no longer conditionally hides content based on hasSlices).

Written by Cursor Bugbot for commit d7ef5ae. This will update automatically on new commits. Configure here.

Footnotes

  1. Please use these labels when submitting a review:
    ❓ #ask: Ask a question.
    💡 #idea: Suggest an idea.
    ⚠️ #issue: Strongly suggest a change.
    🎉 #nice: Share a compliment.

angeloashmore and others added 2 commits February 23, 2026 15:16
Always render the root div in the slice simulator iframe, removing
the render-time window check that caused a server/client mismatch.
The simulator manager now initializes once rather than re-running on
router identity changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Comment thread src/SliceSimulator.tsx Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug Report: Page Builder Live Preview Fails After Multiple Edits

1 participant