[bug]: Self-hosted v1.3.0 — React hydration error (#418/#423) causes error boundary on mobile browsers
Description
Self-hosted Plane v1.3.0 Community Edition shows the "Looks like something went wrong!" error boundary page on mobile browsers (tested on iOS Chrome and Safari). Desktop browsers show console errors but recover. The v1.3.0 release notes mention "Fixed logo spinner hydration and theme loading issues", but the fix appears incomplete for self-hosted Docker images.
Steps to reproduce
- Deploy Plane v1.3.0 Community Edition self-hosted using
makeplane/plane-frontend:stable(or:v1.3.0) Docker image - Open the instance URL on a mobile browser (iPhone Chrome or Safari)
- The error boundary page appears: "Looks like something went wrong!"
Desktop browsers show the same React errors in the console but recover and render correctly.
Expected behavior
The app should load on both desktop and mobile browsers without triggering the error boundary.
Console errors
Error: Minified React error #418; visit https://reactjs.org/docs/error-decoder.html?invariant=418
at gu (index-VH9TOfLF.js:6:4907)
at sa (index-VH9TOfLF.js:8:45647)
...
Uncaught Error: Minified React error #423; visit https://reactjs.org/docs/error-decoder.html?invariant=423
at sa (index-VH9TOfLF.js:8:45307)
...
- #418: "Hydration failed because the server rendered HTML didn't match the client"
- #423: "There was an error while hydrating but React was able to recover by instead client rendering the entire root"
Root cause analysis
The source code in apps/web/app/root.tsx correctly has suppressHydrationWarning on <html> and <body>, and uses next-themes ThemeProvider. However, the built Docker image's static HTML does not include the pre-rendered HydrateFallback (LogoSpinner) in the body:
Self-hosted HTML (from Docker image):
<body>
<div id="context-menu-portal"></div>
<div id="editor-portal"></div>
<script>/* inline theme script */</script>
<div></div> <!-- empty React root -->
</body>
Plane Cloud (app.plane.so) HTML:
<body>
<div id="context-menu-portal"></div>
<div id="editor-portal"></div>
<div style="position:relative;display:flex;height:100vh;...">
<img src="/assets/logo-spinner-light-..." alt="logo"> <!-- pre-rendered fallback -->
</div>
</body>
The self-hosted build outputs an empty root div while the Cloud build includes the HydrateFallback content. The theme initialization script modifies <html> attributes before React hydrates, creating a mismatch that triggers the error boundary on mobile.
Environment
- Plane version: v1.3.0 Community Edition
- Deployment: Docker (self-hosted via Coolify)
- Images:
makeplane/plane-frontend:v1.3.0(Docker Hub, digestsha256:5116ac06c2b5f...) - Affected: iOS Safari 17+, iOS Chrome — error boundary triggered
- Not affected: Desktop Chrome, Desktop Safari — console errors only, app recovers
- Previous version: v1.2.3 loads (same
hydrateRoot+ theme script) but does not trigger error boundary on mobile
Possible fix
The self-hosted Docker image build should include the HydrateFallback component (LogoSpinner) pre-rendered in the static HTML, matching the Plane Cloud build output.
Source: makeplane/plane