Site Editor: Fix unsupported theme flash on direct URL navigation#76465
Site Editor: Fix unsupported theme flash on direct URL navigation#76465
Conversation
|
Size Change: +47 B (0%) Total Size: 7.66 MB
ℹ️ View Unchanged
|
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
When navigating directly to a Site Editor URL (e.g. a template edit screen), the sidebar briefly flashes "The theme you are currently using does not support this screen" before the correct content appears. This happens because route area resolvers check `siteData.currentTheme?.is_block_theme` to decide what to render, but `currentTheme` is fetched asynchronously and is initially null. The optional chaining evaluates to undefined (falsy), so the resolvers fall through to `<SidebarNavigationScreenUnsupported />`. Add an `isThemeDataLoaded` helper that distinguishes "theme data not yet loaded" from "classic theme." Area resolvers that render the unsupported screen now return null while theme data is pending, rendering nothing until the theme type is actually known. Co-authored-by: Claude <noreply@anthropic.com>
dce231f to
85c7bab
Compare
There was a problem hiding this comment.
Pull request overview
Fixes a transient “unsupported theme” warning that appears when navigating directly to Site Editor URLs on block themes, caused by currentTheme being null while the theme is still resolving via REST.
Changes:
- Added
isThemeDataLoaded( siteData )helper to detect whensiteData.currentThemehas been populated. - Updated multiple route area resolvers to return early while theme data is pending, avoiding rendering
<SidebarNavigationScreenUnsupported />during the loading window. - Applied the early-return pattern across templates/pages/navigation/home/stylebook routes.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/edit-site/src/components/site-editor-routes/utils.js | Adds isThemeDataLoaded() helper used by route resolvers. |
| packages/edit-site/src/components/site-editor-routes/templates.js | Prevents unsupported-screen flash in templates sidebar/mobile while theme data is pending. |
| packages/edit-site/src/components/site-editor-routes/template-item.js | Prevents unsupported-screen flash for individual template route areas while theme data is pending. |
| packages/edit-site/src/components/site-editor-routes/stylebook.js | Avoids rendering unsupported sidebar until theme data is known. |
| packages/edit-site/src/components/site-editor-routes/pages.js | Prevents unsupported-screen flash in pages sidebar/mobile while theme data is pending. |
| packages/edit-site/src/components/site-editor-routes/page-item.js | Prevents unsupported-screen flash for individual page route areas while theme data is pending. |
| packages/edit-site/src/components/site-editor-routes/navigation.js | Prevents unsupported-screen flash in navigation sidebar/mobile while theme data is pending. |
| packages/edit-site/src/components/site-editor-routes/navigation-item.js | Prevents unsupported-screen flash for individual navigation item route areas while theme data is pending. |
| packages/edit-site/src/components/site-editor-routes/home.js | Avoids rendering unsupported screen on home route until theme data is known. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const isBlockTheme = siteData.currentTheme?.is_block_theme; | ||
| return isBlockTheme || | ||
| if ( ! isThemeDataLoaded( siteData ) ) { | ||
| return null; |
There was a problem hiding this comment.
In mobile viewports, returning null here makes areas.mobile falsy, so the layout treats the route as having no mobile area and falls back to rendering the sidebar/content/preview layout instead (see edit-site/src/components/layout/index.js checks like isMobileViewport && areas.mobile). If the intent is “render nothing while theme is loading” but still keep the mobile area active, return an empty React node (e.g. an empty fragment) instead of null (or adjust the layout checks to differentiate undefined vs null).
| return null; | |
| return <></>; |
| const isBlockTheme = siteData.currentTheme?.is_block_theme; | ||
| return isBlockTheme ? ( | ||
| if ( ! isThemeDataLoaded( siteData ) ) { | ||
| return null; |
There was a problem hiding this comment.
Returning null here makes areas.mobile falsy, which the Site Editor layout interprets as “no mobile area provided” and it will render the non-mobile sidebar layout on mobile viewports until theme data arrives. To keep the route in its mobile/fullscreen mode while still rendering nothing during loading, return an empty React node (e.g. an empty fragment) rather than null.
| return null; | |
| return <></>; |
| const isBlockTheme = siteData.currentTheme?.is_block_theme; | ||
| return isBlockTheme ? ( | ||
| if ( ! isThemeDataLoaded( siteData ) ) { | ||
| return null; |
There was a problem hiding this comment.
Returning null from the mobile area makes areas.mobile falsy, so the layout may fall back to rendering the sidebar layout on mobile viewports until theme data is available. If you want the mobile area to be considered “present” while rendering nothing, return an empty React node (e.g. an empty fragment) instead of null.
| return null; | |
| return <></>; |
| const isBlockTheme = siteData.currentTheme?.is_block_theme; | ||
| return isBlockTheme ? ( | ||
| if ( ! isThemeDataLoaded( siteData ) ) { | ||
| return null; |
There was a problem hiding this comment.
Returning null here makes areas.preview falsy, so the layout skips rendering the preview canvas container entirely until theme data loads, then mounts it later. If you want to keep the preview area reserved (avoiding layout shifts) while still rendering nothing during loading, return an empty React node (e.g. an empty fragment) instead of null.
| return null; | |
| return <></>; |
| const isBlockTheme = siteData.currentTheme?.is_block_theme; | ||
| return isBlockTheme ? ( | ||
| if ( ! isThemeDataLoaded( siteData ) ) { | ||
| return null; |
There was a problem hiding this comment.
Because the layout renders the preview canvas only when areas.preview is truthy (areas.preview && ...), returning null here suppresses the entire preview container while theme data is loading, then mounts it later. If you want to avoid layout shifts while still rendering nothing during loading, return an empty React node (e.g. an empty fragment) instead of null so the preview area is still considered present.
| return null; | |
| return <></>; |
| const isBlockTheme = siteData.currentTheme?.is_block_theme; | ||
| return isBlockTheme ? ( | ||
| if ( ! isThemeDataLoaded( siteData ) ) { | ||
| return null; |
There was a problem hiding this comment.
Returning null from the mobile area makes areas.mobile falsy, which can cause the layout to temporarily treat this route as not having a mobile area and render the sidebar layout on mobile viewports instead. If the goal is to render nothing while loading but keep the mobile area active, return an empty React node (e.g. an empty fragment) rather than null.
| return null; | |
| return <></>; |
| const isBlockTheme = siteData.currentTheme?.is_block_theme; | ||
| return isBlockTheme ? ( | ||
| if ( ! isThemeDataLoaded( siteData ) ) { | ||
| return null; |
There was a problem hiding this comment.
The preview canvas is only rendered when areas.preview is truthy in the Site Editor layout. Returning null here removes the preview container while theme data is loading, then adds it later, which can cause a noticeable layout shift. Consider returning an empty React node (e.g. empty fragment) during loading instead of null so the preview area remains “present” while still rendering nothing.
| return null; | |
| return <></>; |
| const isBlockTheme = siteData.currentTheme?.is_block_theme; | ||
| return isBlockTheme ? ( | ||
| if ( ! isThemeDataLoaded( siteData ) ) { | ||
| return null; |
There was a problem hiding this comment.
Returning null from the mobile area makes areas.mobile falsy, which the layout interprets as “no mobile area”, potentially rendering the non-mobile sidebar layout on mobile viewports during the loading window. To keep the route in mobile mode while rendering nothing, return an empty React node (e.g. an empty fragment) instead of null.
| return null; | |
| return <></>; |
| const isBlockTheme = siteData.currentTheme?.is_block_theme; | ||
| if ( ! isBlockTheme ) { | ||
| if ( ! isThemeDataLoaded( siteData ) ) { | ||
| return null; |
There was a problem hiding this comment.
Returning null here makes areas.mobile falsy; on mobile viewports this can cause the layout to fall back to rendering the sidebar/content/preview layout (because it checks areas.mobile truthiness) until theme data is available. If you want a blank mobile screen without switching layouts, return an empty React node (e.g. an empty fragment) instead of null.
| return null; | |
| return <></>; |
| const isBlockTheme = siteData.currentTheme?.is_block_theme; | ||
| return isBlockTheme ? ( | ||
| if ( ! isThemeDataLoaded( siteData ) ) { | ||
| return null; |
There was a problem hiding this comment.
Returning null from the mobile area makes areas.mobile falsy, so on mobile viewports the layout may temporarily render the non-mobile sidebar layout (it uses areas.mobile truthiness to decide) until theme data arrives. If you want to render nothing while still keeping the mobile area active, return an empty React node (e.g. an empty fragment) rather than null.
| return null; | |
| return <></>; |
|
Flaky tests detected in 85c7bab. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/23353913395
|
|
The copilot reviews all boil down to the same thing: returning null makes areas.mobile / areas.preview falsy, which causes the layout to treat the route as not having that area at all — potentially causing layout shifts or briefly showing the wrong layout mode on mobile. It sounds technically true, but when I test with a mobile viewport I don't see layout shifts or incorrect modes. |
What?
Fix a brief flash of "The theme you are currently using does not support this screen" when navigating directly to a Site Editor URL with a block theme.
This closes issue #76462
Why?
When loading a Site Editor URL directly (e.g.
?p=%2Fwp_template%2F...&canvas=edit), the route area resolvers checksiteData.currentTheme?.is_block_themeto decide whether to render the actual content or<SidebarNavigationScreenUnsupported />. However,currentThemeis fetched asynchronously via the REST API and is initiallynull. The optional chaining evaluates toundefined(falsy), so the resolvers briefly render the unsupported theme warning before the theme data arrives and the correct UI takes over.How?
Add an
isThemeDataLoaded()helper toutils.jsthat checks whethercurrentThemehas been populated yet. Area resolvers that render<SidebarNavigationScreenUnsupported />now returnnullearly when theme data is still pending, rendering nothing in those slots until the theme type is actually known. Areas that already returnedundefinedfor non-block themes (likepreviewandcontent) are unaffected since they were already safe.This is an AI-assisted contribution (Claude). All code has been reviewed and tested by the author.
Testing Instructions
wp-envwith a block theme active (e.g. Twenty Twenty-Five)./wp-admin/site-editor.php?p=%2Fwp_template%2Fpub%2Ftwentytwentyfive%2F%2Findex&canvas=edit/wp-admin/site-editor.php. Verify the unsupported theme warning still appears and persists as expected.Testing Instructions for Keyboard
No UI interaction changes — this only affects the timing of what renders in existing layout areas.