diff --git a/projects/plugins/boost/app/assets/src/js/features/critical-css/error-description/error-description.tsx b/projects/plugins/boost/app/assets/src/js/features/critical-css/error-description/error-description.tsx
index 1514a87b7b1da..865dc896ad551 100644
--- a/projects/plugins/boost/app/assets/src/js/features/critical-css/error-description/error-description.tsx
+++ b/projects/plugins/boost/app/assets/src/js/features/critical-css/error-description/error-description.tsx
@@ -1,21 +1,13 @@
import classNames from 'classnames';
import { createInterpolateElement } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
-import {
- describeErrorSet,
- suggestion,
- rawError,
-} from '../lib/describe-critical-css-recommendations';
-import actionLinkInterpolateVar from '$lib/utils/action-link-interpolate-var';
-import { type InterpolateVars } from '$lib/utils/interplate-vars-types';
-import supportLinkInterpolateVar from '$lib/utils/support-link-interpolate-var';
+import { describeErrorSet, rawError } from '../lib/describe-critical-css-recommendations';
import FoldingElement from '../folding-element/folding-element';
import MoreList from '../more-list/more-list';
import styles from './error-description.module.scss';
import Suggestion from '../suggestion/suggestion';
import { CriticalCssErrorDescriptionTypes, FormattedURL } from './types';
-import { useRegenerateCriticalCssAction } from '../lib/stores/critical-css-state';
-import { useNavigate } from 'react-router-dom';
+import getCriticalCssErrorSetInterpolateVars from '$lib/utils/get-critical-css-error-set-interpolate-vars';
/**
* Remove GET parameters that are used to cache-bust from display URLs, as they add visible noise
@@ -23,7 +15,7 @@ import { useNavigate } from 'react-router-dom';
*
* @param url The URL to strip cache parameters from.
*/
-function stripCacheParams( url: string ): string {
+export function stripCacheParams( url: string ): string {
const urlObj = new URL( url );
urlObj.searchParams.delete( 'donotcachepage' );
return urlObj.toString();
@@ -49,26 +41,7 @@ const CriticalCssErrorDescription: React.FC< CriticalCssErrorDescriptionTypes >
} );
const rawErrors = rawError( errorSet );
- const regenerateAction = useRegenerateCriticalCssAction();
- const navigate = useNavigate();
-
- function retry() {
- regenerateAction.mutate();
- navigate( '/' );
- }
-
- const intepolateVars: InterpolateVars = {
- ...actionLinkInterpolateVar( retry, 'retry' ),
- ...supportLinkInterpolateVar(),
- b: ,
- };
-
- if ( 'listLink' in suggestion( errorSet ) ) {
- intepolateVars.link = (
- // eslint-disable-next-line jsx-a11y/anchor-has-content
-
- );
- }
+ const intepolateVars = getCriticalCssErrorSetInterpolateVars( errorSet );
return (
diff --git a/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.module.scss b/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.module.scss
index e3466bac0440b..747d8ec4e901d 100644
--- a/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.module.scss
+++ b/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.module.scss
@@ -2,7 +2,6 @@
&.foldable-element-control {
color: var( --primary-black );
font-size: 16px;
- margin-bottom: 24px;
}
}
@@ -27,6 +26,16 @@
animation-name: fadeIn;
}
-.expanded {
- margin-bottom: 24px;
+.expanded p {
+ padding-top: 1em;
+ padding-bottom: 1em;
+ margin: 0 !important;
+}
+
+.expanded p:last-child {
+ padding-bottom: 0;
+}
+
+.foldable-element-control {
+ font-weight: 600;
}
diff --git a/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.tsx b/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.tsx
index b48f3cda684d9..b48e641edf509 100644
--- a/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.tsx
+++ b/projects/plugins/boost/app/assets/src/js/features/critical-css/folding-element/folding-element.tsx
@@ -2,6 +2,8 @@ import useMeasure from 'react-use-measure';
import { animated, useSpring } from '@react-spring/web';
import classNames from 'classnames';
import { useState } from 'react';
+import ChevronDown from '$svg/chevron-down';
+import ChevronUp from '$svg/chevron-up';
import styles from './folding-element.module.scss';
type PropTypes = {
@@ -34,6 +36,7 @@ const FoldingElement: React.FC< PropTypes > = ( {
onClick={ () => setExpanded( ! expanded ) }
>
{ label }
+ { expanded ?
:
}
= ( {
showRetry,
} ) => {
const primaryErrorSet = getPrimaryErrorSet( cssState );
- const showErrorDescription = primaryErrorSet && cssState.status === 'generated';
- const showFoldingElement = showErrorDescription || cssState.status_error;
+ const showLearnSection = primaryErrorSet && cssState.status === 'generated';
+ return (
+ <>
+
+ { showLearnSection ? (
+ <>
+
+
+
+
{ __( 'Please follow the troubleshooting steps below', 'jetpack-boost' ) }
+
+
+
+
+ >
+ ) : (
+
+ ) }
+
+ >
+ );
+};
+
+const Description = ( { errorSet }: { errorSet: ErrorSet } ) => {
+ const displayUrls = formatErrorSetUrls( errorSet );
+
+ return (
+
+ { createInterpolateElement( describeErrorSet( errorSet ), {
+ b: ,
+ } ) }{ ' ' }
+ { displayUrls.map( ( { href, label }, index ) => (
+
+ { label }
+
+ ) ) }
+
+ );
+};
+
+const Steps = ( { errorSet }: { errorSet: ErrorSet } ) => {
+ const details = suggestion( errorSet );
+ if ( ! details.list ) {
+ return null;
+ }
+
+ const interpolateVars = getCriticalCssErrorSetInterpolateVars( errorSet );
+
+ return ;
+};
+
+const DocumentationSection = ( {
+ message,
+ errorType,
+}: {
+ message?: string;
+ errorType: string;
+} ) => {
+ if ( message === undefined ) {
+ message = __(
+ 'If you are still experiencing this issue, learn more from our documentation.',
+ 'jetpack-boost'
+ );
+ }
+
+ return (
+
+ { createInterpolateElement( message, {
+ link: (
+ // eslint-disable-next-line jsx-a11y/anchor-has-content
+
+ ),
+ } ) }
+
+ );
+};
+
+const OtherErrors = ( { cssState, retry, showRetry, supportLink }: ShowStopperErrorTypes ) => {
const firstTimeError = __(
'An unexpected error has occurred. As this error may be temporary, please try and refresh the Critical CSS.',
'jetpack-boost'
@@ -33,47 +131,61 @@ const ShowStopperError: React.FC< ShowStopperErrorTypes > = ( {
);
return (
-
- { __( 'Refresh', 'jetpack-boost' ) }
-
- ) : (
-
- { __( 'Contact Support', 'jetpack-boost' ) }
-
- )
- }
- >
- { showRetry ? firstTimeError : secondTimeError }
- { showFoldingElement && (
-
-
- { showErrorDescription ? (
-
- ) : (
+ <>
+ { cssState.status_error === 'css-gen-library-failure' ? (
+ <>
+
+ { __(
+ 'Critical CSS Generator library is either not found or invalid.',
+ 'jetpack-boost'
+ ) }
+
+
Learn how to fix this by visiting our documentation.',
+ 'jetpack-boost'
+ ) }
+ errorType={ cssState.status_error }
+ />
+
+ { createInterpolateElement(
+ __(
+ 'If the problem has been resolved, refresh the page and click here to try regenerating critical css.',
+ 'jetpack-boost'
+ ),
+ {
+ ...actionLinkInterpolateVar( retry, 'retry' ),
+ }
+ ) }
+
+ >
+ ) : (
+ <>
+ { showRetry ? firstTimeError : secondTimeError }
+
+ { sprintf(
+ /* translators: %s: error message */
+ __( `Error: %s`, 'jetpack-boost' ),
cssState.status_error
) }
-
-
+
+ { showRetry ? (
+
+ { __( 'Refresh', 'jetpack-boost' ) }
+
+ ) : (
+
+ { __( 'Contact Support', 'jetpack-boost' ) }
+
+ ) }
+ >
) }
-
+ >
);
};
diff --git a/projects/plugins/boost/app/assets/src/js/lib/utils/format-error-set-urls.ts b/projects/plugins/boost/app/assets/src/js/lib/utils/format-error-set-urls.ts
new file mode 100644
index 0000000000000..9089700387dd3
--- /dev/null
+++ b/projects/plugins/boost/app/assets/src/js/lib/utils/format-error-set-urls.ts
@@ -0,0 +1,18 @@
+import { stripCacheParams } from '$features/critical-css/error-description/error-description';
+import { FormattedURL } from '$features/critical-css/error-description/types';
+import { ErrorSet } from '$features/critical-css/lib/critical-css-errors';
+
+function formatErrorSetUrls( errorSet: ErrorSet ): FormattedURL[] {
+ return Object.entries( errorSet.byUrl ).map( ( [ url, error ] ) => {
+ let href = url;
+ if ( error.meta.url && typeof error.meta.url === 'string' ) {
+ href = error.meta.url;
+ }
+ return {
+ href,
+ label: stripCacheParams( url ),
+ };
+ } );
+}
+
+export default formatErrorSetUrls;
diff --git a/projects/plugins/boost/app/assets/src/js/lib/utils/get-critical-css-error-set-interpolate-vars.tsx b/projects/plugins/boost/app/assets/src/js/lib/utils/get-critical-css-error-set-interpolate-vars.tsx
new file mode 100644
index 0000000000000..005fba934c65c
--- /dev/null
+++ b/projects/plugins/boost/app/assets/src/js/lib/utils/get-critical-css-error-set-interpolate-vars.tsx
@@ -0,0 +1,34 @@
+import { useNavigate } from 'react-router-dom';
+import actionLinkInterpolateVar from '$lib/utils/action-link-interpolate-var';
+import { InterpolateVars } from '$lib/utils/interplate-vars-types';
+import supportLinkInterpolateVar from '$lib/utils/support-link-interpolate-var';
+import { useRegenerateCriticalCssAction } from '$features/critical-css/lib/stores/critical-css-state';
+import { suggestion } from '$features/critical-css/lib/describe-critical-css-recommendations';
+import { ErrorSet } from '$features/critical-css/lib/critical-css-errors';
+
+function getCriticalCssErrorSetInterpolateVars( errorSet: ErrorSet ) {
+ const regenerateAction = useRegenerateCriticalCssAction();
+ const navigate = useNavigate();
+
+ function retry() {
+ regenerateAction.mutate();
+ navigate( '/' );
+ }
+
+ const interpolateVars: InterpolateVars = {
+ ...actionLinkInterpolateVar( retry, 'retry' ),
+ ...supportLinkInterpolateVar(),
+ b: ,
+ };
+
+ if ( 'listLink' in suggestion( errorSet ) ) {
+ interpolateVars.link = (
+ // eslint-disable-next-line jsx-a11y/anchor-has-content
+
+ );
+ }
+
+ return interpolateVars;
+}
+
+export default getCriticalCssErrorSetInterpolateVars;
diff --git a/projects/plugins/boost/app/assets/src/js/lib/utils/get-support-link-critical-css.ts b/projects/plugins/boost/app/assets/src/js/lib/utils/get-support-link-critical-css.ts
new file mode 100644
index 0000000000000..8c51371296e23
--- /dev/null
+++ b/projects/plugins/boost/app/assets/src/js/lib/utils/get-support-link-critical-css.ts
@@ -0,0 +1,24 @@
+function getPrettyError( error: string ) {
+ const errorMap: { [ key: string ]: string } = {
+ SuccessTargetError: 'success-target-error',
+ UrlError: 'url-error',
+ HttpError: 'http-error',
+ UnknownError: 'unknown-error',
+ CrossDomainError: 'cross-domain-error',
+ LoadTimeoutError: 'load-timeout-error',
+ RedirectError: 'redirect-error',
+ UrlVerifyError: 'url-verify-error',
+ EmptyCSSError: 'empty-css-error',
+ XFrameDenyError: 'x-frame-deny-error',
+ };
+
+ return errorMap[ error as keyof typeof errorMap ] || error;
+}
+
+function getSupportLinkCriticalCss( errorType: string ) {
+ return `https://jetpack.com/support/jetpack-boost/troubleshooting-critical-css-issues/#${ getPrettyError(
+ errorType
+ ) }`;
+}
+
+export default getSupportLinkCriticalCss;
diff --git a/projects/plugins/boost/app/assets/src/js/pages/critical-css-advanced/critical-css-advanced.module.scss b/projects/plugins/boost/app/assets/src/js/pages/critical-css-advanced/critical-css-advanced.module.scss
index 67aba8e308924..a8705bd93ab49 100644
--- a/projects/plugins/boost/app/assets/src/js/pages/critical-css-advanced/critical-css-advanced.module.scss
+++ b/projects/plugins/boost/app/assets/src/js/pages/critical-css-advanced/critical-css-advanced.module.scss
@@ -18,7 +18,7 @@
position: relative;
border: 1px solid $gray_5;
border-radius: 4px;
- padding: 24px 69px 0 27px;
+ padding: 24px 69px 24px 27px;
li {
@include word-wrap();
diff --git a/projects/plugins/boost/app/assets/src/js/svg/chevron-up.tsx b/projects/plugins/boost/app/assets/src/js/svg/chevron-up.tsx
index 82b720c686961..11fc5ccb964cb 100644
--- a/projects/plugins/boost/app/assets/src/js/svg/chevron-up.tsx
+++ b/projects/plugins/boost/app/assets/src/js/svg/chevron-up.tsx
@@ -11,7 +11,7 @@ const ChevronUp = () => (
/>
-
+
);
diff --git a/projects/plugins/boost/changelog/update-critical-css-error-ui b/projects/plugins/boost/changelog/update-critical-css-error-ui
new file mode 100644
index 0000000000000..20e9294575b43
--- /dev/null
+++ b/projects/plugins/boost/changelog/update-critical-css-error-ui
@@ -0,0 +1,4 @@
+Significance: patch
+Type: changed
+
+Critical CSS: Improve UI when errors are present.