Skip to content

feat: @W-22204286 add maintenance mode page for 503/sfdc_maintenance responses - #3827

Merged
kevinxh merged 8 commits into
developfrom
priand/maintenance_mode_page
May 12, 2026
Merged

feat: @W-22204286 add maintenance mode page for 503/sfdc_maintenance responses#3827
kevinxh merged 8 commits into
developfrom
priand/maintenance_mode_page

Conversation

@priandsf

@priandsf priandsf commented May 8, 2026

Copy link
Copy Markdown
Contributor

Enable throwOnMaintenanceHeader in commerce-sdk-react, propagate MaintenanceError as 503 through the SSR and client error pipelines, and render a new _maintenance-error component that displays either a shared CDN-hosted page (proxied via /api/maintenance-page) or a built-in fallback, configurable via app.pages.maintenancePage.

Description

Maintenance Mode Page

Summary

Adds a dedicated maintenance mode page that is automatically displayed when the Commerce API signals that the site is under maintenance via the sfdc_maintenance response header.

How it works

Detectioncommerce-sdk-isomorphic already throws a MaintenanceError when it detects the sfdc_maintenance header and throwOnMaintenanceHeader is enabled. This PR enables that flag by hardcoding throwOnMaintenanceHeader: true in commerce-sdk-react's provider config (alongside the existing throwOnBadResponse: true).

Error propagationMaintenanceError is not an HTTPError, so it was previously swallowed as a generic 500. Three places are fixed to correctly propagate it as a 503:

  • with-react-query/doInitAppState — rethrows MaintenanceError instead of swallowing it during SSR query prefetching
  • react-rendering/logAndFormatError — formats it with status: 503 instead of 500
  • app-error-boundary — detects it by err.name === 'MaintenanceError' in both onGetPropsError (server/getProps path) and getDerivedStateFromError (client render path)

Client-sideuseErrorBoundary: (err) => err?.name === 'MaintenanceError' is added to the React Query default options so that MaintenanceError thrown by client-side queries is rethrown into the React error boundary rather than silently held in query state.

Rendering_error/index.jsx dispatches to a new _maintenance-error component when status === 503.

Maintenance page content — The _maintenance-error component supports two modes, configured via config.app.pages.maintenancePage:

  • sharedMaintenancePage: true (default) — fetches a shared HTML maintenance page from a configurable CDN URL, proxied through a new /api/maintenance-page Express endpoint to avoid CORS restrictions
  • sharedMaintenancePage: false — displays a built-in branded fallback message

Types of Changes

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Documentation update
  • Breaking change (could cause existing functionality to not work as expected)
  • Other changes (non-breaking changes that does not fit any of the above)

Breaking changes include:

  • Removing a public function or component or prop
  • Adding a required argument to a function
  • Changing the data type of a function parameter or return value
  • Adding a new peer dependency to package.json

Changes

  • (change1)

How to Test-Drive This PR

  • Verify maintenance page renders when sfdc_maintenance: system or sfdc_maintenance: site header is returned by the API
  • Verify CDN content is displayed when sharedMaintenancePage: true and cdnUrl is configured
  • Verify built-in fallback message is displayed when sharedMaintenancePage: false
  • Verify built-in fallback is shown when the CDN fetch fails
  • Verify no flash of the fallback message before CDN content loads
  • Verify generic error page still renders for non-503 errors
  • Run _maintenance-error unit tests: jest app/components/_maintenance-error

Checklists

General

  • Changes are covered by test cases
  • CHANGELOG.md updated with a short description of changes (not required for documentation updates)

Accessibility Compliance

You must check off all items in one of the follow two lists:

  • There are no changes to UI

or...

Localization

  • Changes include a UI text update in the Retail React App (which requires translation)

Enable throwOnMaintenanceHeader in commerce-sdk-react, propagate
MaintenanceError as 503 through the SSR and client error pipelines,
and render a new _maintenance-error component that displays either
a shared CDN-hosted page (proxied via /api/maintenance-page) or a
built-in fallback, configurable via app.pages.maintenancePage.
@priandsf
priandsf requested a review from a team as a code owner May 8, 2026 17:25
@git2gus

git2gus Bot commented May 8, 2026

Copy link
Copy Markdown

Git2Gus App is installed but the .git2gus/config.json doesn't have right values. You should add the required configuration.

@cc-prodsec

cc-prodsec commented May 8, 2026

Copy link
Copy Markdown
Collaborator

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@priandsf
priandsf enabled auto-merge May 8, 2026 19:47
Comment thread packages/commerce-sdk-react/CHANGELOG.md Outdated
Comment thread packages/pwa-kit-react-sdk/CHANGELOG.md Outdated
Comment thread packages/template-retail-react-app/config/default.js
Comment thread packages/template-retail-react-app/app/ssr.js
shethj
shethj previously approved these changes May 12, 2026

@kevinxh kevinxh May 12, 2026

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.

_{component} is a PWA Kit SDK file system convention for SDK level special components.

It indicates that this component is being processed by the SDK, and the SDK will look at the user land /app/components/ folder for these special components, if not found it will fallback to the SDK default implementation.

The current file system convention we have are:

_app_config - wraps the top level application with providers
_app - root application
_document - the HTML shell (equivalent to next.js layout.js)
_error - error page (equivalent to next.js error.js)

Did you want to introduce the maintainence page as a new member of the SDK component family? or is this just a template level component, if so, we should remove the _ prefix

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@kevinxh So I copied that from _error, as I think it should behave the same. Is there any issue with it?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does it make sense to move the component to SDK?

@kevinxh kevinxh May 12, 2026

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.

If the intent is to register _maintenance-error as a new framework-level file convention (alongside _app, _document, _error, etc.), there are two additional changes needed to make it a true SDK-level component:

  1. Add a default _maintenance-error implementation under https://github.com/SalesforceCommerceCloud/pwa-kit/tree/develop/packages/pwa-kit-react-sdk/src/ssr/universal/components so the SDK has a fallback.
  2. Register it in the webpack override list at https://github.com/SalesforceCommerceCloud/pwa-kit/blob/develop/packages/pwa-kit-dev/src/configs/webpack/plugins.js#L67-L87 so userland overrides are resolved correctly.

That said, my recommendation is to drop the _ prefix here. As used in this PR, _maintenance-error is consumed internally by the error component and doesn’t need a dedicated SSR code path or override hook — it’s a template-level component, not a framework-level one. Reserving the _ convention for components that genuinely participate in the SDK’s resolution mechanism keeps the convention meaningful and avoids implying behavior that isn’t wired up.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I dropped it - done. Is that documented somewhere?

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.

@kevinxh
kevinxh disabled auto-merge May 12, 2026 22:05
@kevinxh
kevinxh merged commit 235f231 into develop May 12, 2026
39 of 41 checks passed
@kevinxh
kevinxh deleted the priand/maintenance_mode_page branch May 12, 2026 22:05
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.

5 participants