Skip to content

Guard settings destructure so the settings page doesn't blank when classifAISettings is missing#1135

Merged
dkotter merged 3 commits into
10up:developfrom
thisismyurl:fix/1073-guard-settings-global
Jul 7, 2026
Merged

Guard settings destructure so the settings page doesn't blank when classifAISettings is missing#1135
dkotter merged 3 commits into
10up:developfrom
thisismyurl:fix/1073-guard-settings-global

Conversation

@thisismyurl

@thisismyurl thisismyurl commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Hey folks,

If window.classifAISettings is ever undefined when the settings bundle loads, the whole settings screen goes blank with nothing but a console error to explain it. The cause is the module-scope destructure at the top of classifai-settings/index.jsconst { services, features } = window.classifAISettings; runs the moment the module is imported, before React mounts, so there's no error boundary between it and the user. Anything that shifts script order or timing (a caching or optimization plugin deferring or reordering the enqueue, an asset that fails to localize) leaves the global undefined and that line throws a TypeError that takes the page down.

This PR guards just that destructure: default services and features to {} and fall back to {} when the global is missing. The downstream code already treats these defensively (features[ service ] || {}), so an empty object degrades into an empty settings shell instead of a white screen. The issue also floats a React error boundary and a NitroPack exclusion; I kept this change to the one-line guard that stops the crash, since those are larger design calls that deserve their own discussion. Glad to follow up on either if you want them.

One thing worth flagging plainly: an automated regression test here is awkward. There's no JS unit harness (only PHP unit and the Playwright e2e suite), and the e2e environment always localizes window.classifAISettings, so a test would have to force the failure synthetically — aborting or blanking the settings script via page.route before mount — to reproduce the undefined-global state. Your e2e suite already uses page.route for that kind of interception, so I'm glad to add that guard if you'd like it; I held off because it exercises a forced condition rather than a natural one, and the change itself is a defensive default with no behavior change when the global is present. Your call.

No rendered-UI change comes with this — the guard only affects the crash path when the global is absent, so there's no accessibility surface to review.

Closes #1073

(full disclosure: AI helped me identify the issue and verify my work)

Open WordPress Playground Preview

…assifAISettings is missing

The settings bundle destructured window.classifAISettings at module scope,
before React mounts, so an undefined global (script-order interference from a
caching/optimization plugin) threw a TypeError and blanked the whole settings
page. Default services and features to {} and fall back to {} when the global
is absent; downstream code already treats these defensively.

Closes 10up#1073
Copilot AI review requested due to automatic review settings July 7, 2026 13:54
@thisismyurl thisismyurl requested review from a team, dkotter and jeffpaul as code owners July 7, 2026 13:54

Copilot AI 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.

Pull request overview

This PR defensively reads the settings bootstrap data (window.classifAISettings) so the React-based settings UI doesn’t hard-crash at module import time when that global is missing (e.g., due to script reordering/deferral).

Changes:

  • Guard module-scope destructuring of window.classifAISettings by falling back to {} defaults.
  • Add an [Unreleased] changelog entry documenting the fix.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/js/settings/components/classifai-settings/index.js Prevents a module-load TypeError by defaulting services/features when the global settings object is missing.
CHANGELOG.md Documents the fix under [Unreleased].

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/js/settings/components/classifai-settings/index.js
Comment thread CHANGELOG.md

### Fixed

- Settings page no longer crashes to a blank screen when `window.classifAISettings` is undefined (for example when a caching or optimization plugin changes script order); the settings data is now read defensively (props [@thisismyurl](https://github.com/thisismyurl) via [#1135](https://github.com/10up/classifai/pull/1135)).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Note we generally don't include changelog entries in each PR as those are manually pulled at release time

The settings-global guard let `features` default to an empty object, so
FeatureSettingsWrapper could compute an empty serviceFeatures list and then
render <Navigate to={ serviceFeatures[0] } /> with an undefined target,
reintroducing a broken route on the path the guard was meant to protect.
Return null when there are no features to route to.

Addresses the Copilot review feedback on 10up#1135.
@thisismyurl

Copy link
Copy Markdown
Contributor Author

Good catch — that's a real gap. The guard stopped the module-scope crash but left FeatureSettingsWrapper free to navigate to serviceFeatures[0] when features is empty, landing on to={undefined} — exactly the broken route this was meant to prevent. Pushed a small follow-up (0615f0d) that returns null when there's no feature to route to.

On the changelog note: the #1135 link is correct — that placeholder line was left over from before the PR number existed, and I've removed it from the description.

@dkotter dkotter added this to the 3.9.0 milestone Jul 7, 2026
@dkotter dkotter merged commit 5a8a2ca into 10up:develop Jul 7, 2026
31 of 32 checks passed
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.

Settings page blank — JS crash from module-level destructure when classifAISettings is undefined (NitroPack / script order

3 participants