Detect cache when launching store (#48586)

* Remove duplicate

* Add is-coming-soon-page endpoint

* Render invalid cache warning

* Use meta tag instead

* Add url for debug purpose

* Use a different copy for the congrats page when the cache is still shown

* Clean up unused codes

* Guard the api with permission

* Add changefile(s) from automation for the following project(s): woocommerce

* Reuse $is_fse_theme

* Lint fixes

* Update 48586-update-48516-detect-cache-when-launching-store

* Add changefile(s) from automation for the following project(s): woocommerce

* Add changefile(s) from automation for the following project(s): woocommerce

* Update plugins/woocommerce/changelog/48586-update-48516-detect-cache-when-launching-store

Co-authored-by: Chi-Hsuan Huang <chihsuan.tw@gmail.com>

* Add changefile(s) from automation for the following project(s): woocommerce

* changed to js method

* Add changefile(s) from automation for the following project(s): @woocommerce/data, woocommerce

* empty commit to trigger CI

* Add changefile(s) from automation for the following project(s): @woocommerce/data, woocommerce

* empty commit to trigger CI

---------

Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: Chi-Hsuan Huang <chihsuan.tw@gmail.com>
Co-authored-by: rjchow <me@rjchow.com>
This commit is contained in:
Moon 2024-06-19 03:23:29 -07:00 committed by GitHub
parent efc9dc4c62
commit f95d8b240b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 184 additions and 16 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: tweak
Verify if the coming soon cache is displayed when launching the store and alerts the user if it is still present.

View File

@ -1,6 +1,6 @@
export type Settings = {
[ key: string ]: unknown;
} & {
} & { siteUrl?: string; shopUrl?: string } & {
general?: {
[ key: string ]: string;
};

View File

@ -29,12 +29,14 @@ export type CongratsProps = {
isWooExpress: boolean;
completeSurvey: () => void;
children?: React.ReactNode;
siteIsShowingCachedContent: boolean;
};
export const Congrats = ( {
hasCompleteSurvey,
isWooExpress,
completeSurvey,
siteIsShowingCachedContent,
children,
}: CongratsProps ) => {
const copyLink = __( 'Copy link', 'woocommerce' );
@ -116,16 +118,42 @@ export const Congrats = ( {
</div>
<div className="woocommerce-launch-store__congrats-content">
<h1 className="woocommerce-launch-store__congrats-heading">
{ __(
'Congratulations! Your store is now live',
'woocommerce'
) }
{ siteIsShowingCachedContent
? __(
'Congratulations! Your store will launch soon',
'woocommerce'
)
: __(
'Congratulations! Your store is now live',
'woocommerce'
) }
</h1>
<h2 className="woocommerce-launch-store__congrats-subheading">
{ __(
"You've successfully launched your store and are ready to start selling! We can't wait to see your business grow.",
'woocommerce'
) }
{ siteIsShowingCachedContent
? createInterpolateElement(
__(
'Itll be ready to view as soon as your <link></link> have updated. Please wait, or contact your web host to find out how to do this manually.',
'woocommerce'
),
{
link: (
<a
href="https://woocommerce.com/document/server-caches/"
target="_blank"
rel="noreferrer"
>
{ __(
'server caches',
'woocommerce'
) }
</a>
),
}
)
: __(
"You've successfully launched your store and are ready to start selling! We can't wait to see your business grow.",
'woocommerce'
) }
</h2>
<div className="woocommerce-launch-store__congrats-midsection-container">
<div className="woocommerce-launch-store__congrats-visit-store">

View File

@ -43,6 +43,9 @@ export const LaunchYourStoreSuccess = ( props: MainContentComponentProps ) => {
}
isWooExpress={ isWooExpress() }
completeSurvey={ completeSurvey }
siteIsShowingCachedContent={
props.context.siteIsShowingCachedContent
}
>
<h2 className="woocommerce-launch-store__congrats-main-actions-title">
{ __( "What's next?", 'woocommerce' ) }

View File

@ -99,6 +99,9 @@
letter-spacing: -0.1px;
margin: 4px 0 0;
max-width: 560px;
a {
text-decoration: none;
}
}
.woocommerce-launch-store__congrats-main-actions-title {

View File

@ -27,6 +27,7 @@ export type MainContentMachineContext = {
allTasklists: TaskListType[];
activePlugins: string[];
};
siteIsShowingCachedContent: boolean;
};
export type MainContentComponentProps = LaunchYourStoreComponentProps & {
@ -34,6 +35,7 @@ export type MainContentComponentProps = LaunchYourStoreComponentProps & {
};
export type MainContentMachineEvents =
| { type: 'SHOW_LAUNCH_STORE_SUCCESS' }
| { type: 'SHOW_LAUNCH_STORE_PENDING_CACHE' }
| { type: 'EXTERNAL_URL_UPDATE' }
| { type: 'SHOW_LOADING' }
| congratsEvents;
@ -54,6 +56,9 @@ export const mainContentMachine = setup( {
) => {
updateQueryParams( params );
},
assignSiteCachedStatus: assign( {
siteIsShowingCachedContent: true,
} ),
},
guards: {
hasContentLocation: (
@ -78,6 +83,7 @@ export const mainContentMachine = setup( {
allTasklists: [],
activePlugins: [],
},
siteIsShowingCachedContent: false,
},
invoke: {
id: 'contentQueryParamListener',
@ -149,6 +155,10 @@ export const mainContentMachine = setup( {
SHOW_LAUNCH_STORE_SUCCESS: {
target: '#launchStoreSuccess',
},
SHOW_LAUNCH_STORE_PENDING_CACHE: {
actions: [ 'assignSiteCachedStatus' ],
target: '#launchStoreSuccess',
},
SHOW_LOADING: {
target: '#loading',
},

View File

@ -9,12 +9,18 @@ import {
fromPromise,
assign,
spawnChild,
enqueueActions,
} from 'xstate5';
import React from 'react';
import clsx from 'clsx';
import { getQuery, navigateTo } from '@woocommerce/navigation';
import { OPTIONS_STORE_NAME, TaskListType, TaskType } from '@woocommerce/data';
import { dispatch } from '@wordpress/data';
import {
OPTIONS_STORE_NAME,
SETTINGS_STORE_NAME,
TaskListType,
TaskType,
} from '@woocommerce/data';
import { dispatch, resolveSelect } from '@wordpress/data';
import { recordEvent } from '@woocommerce/tracks';
import apiFetch from '@wordpress/api-fetch';
@ -44,6 +50,7 @@ export type SidebarMachineContext = {
launchStoreError?: {
message: string;
};
siteIsShowingCachedContent?: boolean;
};
export type SidebarComponentProps = LaunchYourStoreComponentProps & {
context: SidebarMachineContext;
@ -81,6 +88,64 @@ const getTestOrderCount = async () => {
return result.count;
};
export const pageHasComingSoonMetaTag = async ( {
url,
}: {
url: string;
} ): Promise< boolean > => {
try {
const response = await fetch( url, {
method: 'GET',
credentials: 'omit',
cache: 'no-store',
} );
if ( ! response.ok ) {
throw new Error( `Failed to fetch ${ url }` );
}
const html = await response.text();
const parser = new DOMParser();
const doc = parser.parseFromString( html, 'text/html' );
const metaTag = doc.querySelector(
'meta[name="woo-coming-soon-page"]'
);
if ( metaTag ) {
return true;
}
return false;
} catch ( error ) {
throw new Error( `Error fetching ${ url }: ${ error }` );
}
};
const getSiteCachedStatus = async () => {
const settings = await resolveSelect( SETTINGS_STORE_NAME ).getSettings(
'wc_admin'
);
// if store URL exists, check both storeUrl and siteUrl otherwise only check siteUrl
// we want to check both because there's a chance that caching is especially disabled for woocommerce pages, e.g WPEngine
const requests = [] as Promise< boolean >[];
if ( settings?.shopUrl ) {
requests.push(
pageHasComingSoonMetaTag( {
url: settings.shopUrl,
} )
);
}
if ( settings?.siteUrl ) {
requests.push(
pageHasComingSoonMetaTag( {
url: settings.siteUrl,
} )
);
}
const results = await Promise.all( requests );
return results.some( ( result ) => result );
};
const deleteTestOrders = async ( {
input,
}: {
@ -154,6 +219,10 @@ export const sidebarMachine = setup( {
( { context } ) => context.mainContentMachineRef,
{ type: 'SHOW_LAUNCH_STORE_SUCCESS' }
),
showLaunchStorePendingCache: sendTo(
( { context } ) => context.mainContentMachineRef,
{ type: 'SHOW_LAUNCH_STORE_PENDING_CACHE' }
),
showLoadingPage: sendTo(
( { context } ) => context.mainContentMachineRef,
{ type: 'SHOW_LOADING' }
@ -189,6 +258,11 @@ export const sidebarMachine = setup( {
success
);
},
recordStoreLaunchCachedContentDetected: () => {
recordEvent(
'launch_your_store_hub_store_launch_cached_content_detected'
);
},
},
guards: {
hasSidebarLocation: (
@ -203,11 +277,15 @@ export const sidebarMachine = setup( {
'woocommerce-payments'
);
},
siteIsShowingCachedContent: ( { context } ) => {
return !! context.siteIsShowingCachedContent;
},
},
actors: {
sidebarQueryParamListener,
getTasklist: fromPromise( getLysTasklist ),
getTestOrderCount: fromPromise( getTestOrderCount ),
getSiteCachedStatus: fromPromise( getSiteCachedStatus ),
updateLaunchStoreOptions: fromPromise( launchStoreAction ),
deleteTestOrders: fromPromise( deleteTestOrders ),
fetchCongratsData,
@ -317,13 +395,13 @@ export const sidebarMachine = setup( {
{
src: 'updateLaunchStoreOptions',
onDone: {
target: '#storeLaunchSuccessful',
actions: [
{
type: 'recordStoreLaunchResults',
params: { success: true },
},
],
target: 'checkingForCachedContent',
},
onError: {
actions: [
@ -360,6 +438,23 @@ export const sidebarMachine = setup( {
},
],
},
checkingForCachedContent: {
invoke: [
{
src: 'getSiteCachedStatus',
onDone: {
target: '#storeLaunchSuccessful',
actions: assign( {
siteIsShowingCachedContent: ( { event } ) =>
event.output,
} ),
},
onError: {
target: '#storeLaunchSuccessful',
},
},
],
},
},
},
storeLaunchSuccessful: {
@ -373,7 +468,18 @@ export const sidebarMachine = setup( {
content: 'launch-store-success',
},
},
{ type: 'showLaunchStoreSuccessPage' },
enqueueActions( ( { check, enqueue } ) => {
if ( check( 'siteIsShowingCachedContent' ) ) {
enqueue( {
type: 'showLaunchStorePendingCache',
} );
enqueue( {
type: 'recordStoreLaunchCachedContentDetected',
} );
return;
}
enqueue( { type: 'showLaunchStoreSuccessPage' } );
} ),
],
},
openExternalUrl: {

View File

@ -0,0 +1,4 @@
Significance: minor
Type: tweak
Verify if the coming soon cache is displayed when launching the store and alerts the user if it is still present.

View File

@ -52,17 +52,27 @@ class ComingSoonRequestHandler {
$coming_soon_template = get_query_template( 'coming-soon' );
if ( ! wc_current_theme_is_fse_theme() && $this->coming_soon_helper->is_store_coming_soon() ) {
$is_fse_theme = wc_current_theme_is_fse_theme();
$is_store_coming_soon = $this->coming_soon_helper->is_store_coming_soon();
if ( ! $is_fse_theme && $is_store_coming_soon ) {
get_header();
}
add_action(
'wp_head',
function () {
echo "<meta name='woo-coming-soon-page' content='yes'>";
}
);
include $coming_soon_template;
if ( ! wc_current_theme_is_fse_theme() && $this->coming_soon_helper->is_store_coming_soon() ) {
if ( ! $is_fse_theme && $is_store_coming_soon ) {
get_footer();
}
if ( wc_current_theme_is_fse_theme() ) {
if ( $is_fse_theme ) {
// Since we've already rendered a template, return null to ensure no other template is rendered.
return null;
} else {