fix: replace infinite spinner with static placeholder in Pay Later block editor preview (5801)#4302
Conversation
…review Replaces the infinite spinner with a static message after 5 seconds when the Pay Later messaging preview cannot be resolved in the editor context.
Replaces the infinite spinner with a static message after 5 seconds when the Pay Later messaging preview cannot be resolved in the editor context.
…eview Replaces the infinite spinner with a static message after 5 seconds when the Pay Later messaging preview cannot be resolved in the editor context.
Required to resolve the useScriptParams hook import when running unit tests for the paylater WC blocks.
Covers spinner display, 5s placeholder fallback, successful render, and warning states.
Covers spinner display, 5s placeholder fallback, successful render, and warning states.
Covers spinner display, 5s placeholder fallback, successful render, and warning states.
Test using WordPress PlaygroundThe changes in this pull request can be previewed and tested using a WordPress Playground instance. 🔗 Test this pull request with WordPress Playground What's included:
Login credentials:
Plugin Details:
🤖 Auto-generated for commit 12125ca • Last updated: 2026-04-27T12:46:34.929Z |
Dinamiko
left a comment
There was a problem hiding this comment.
PR looks good, happy to see that you added tests :)
Maybe consider reducing code duplication by extracting logic to a custom hook and a component:
Custom hook
New file: modules/ppcp-paylater-block/resources/js/hooks/use-preview-timeout.js
import { useState, useEffect } from '@wordpress/element';
export const PREVIEW_TIMEOUT_MS = 5000;
/**
* Flips to `true` once `timeoutMs` has elapsed without `loaded` becoming truthy.
* Returns `false` if the preview loaded in time. Cleans up on unmount or when
* `loaded` flips, so no setState-on-unmounted warnings.
*/
export function usePreviewTimeout( loaded, timeoutMs = PREVIEW_TIMEOUT_MS ) {
const [ timedOut, setTimedOut ] = useState( false );
useEffect( () => {
if ( loaded ) {
return;
}
const timer = setTimeout( () => setTimedOut( true ), timeoutMs );
return () => clearTimeout( timer );
}, [ loaded, timeoutMs ] );
return timedOut;
} Shared placeholder component
New file: modules/ppcp-paylater-block/resources/js/components/preview-placeholder.js
import { __ } from '@wordpress/i18n';
import { Spinner } from '@wordpress/components';
export function PreviewPlaceholder( { timedOut } ) {
if ( ! timedOut ) {
return <Spinner />;
}
return (
<p className="ppcp-paylater-preview-placeholder">
{ __(
'Pay Later messaging preview unavailable in editor. Messaging will display on the frontend when eligibility conditions are met.',
'woocommerce-paypal-payments'
) }
</p>
);
}
Problem
When editing the checkout/cart page in the block editor, the Pay Later messaging block could display an infinite spinner that never resolves. This happens when eligibility requirements (merchant status, geolocation, store configuration) cannot be determined in the editor context, causing the PayPal SDK to silently skip rendering without calling
onRender.Solution
Added a 5-second timeout mechanism to all three Pay Later block editor components. If the messaging preview has not loaded within 5 seconds, the spinner is replaced with a static placeholder:
If the preview loads successfully within 5 seconds, behavior is unchanged.
Changes
CheckoutPayLaterMessagesBlock/edit.js— timeout + placeholderCartPayLaterMessagesBlock/edit.js— timeout + placeholderppcp-paylater-block/resources/js/edit.js— timeout + placeholdertests/js/jest.config.json— added@ppcp-paylater-blockJest aliasTesting
Switch the WooCommerce store currency to one where Pay Later messaging is not supported — the placeholder should appear after 5 seconds.
Notes