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:
parent
efc9dc4c62
commit
f95d8b240b
|
@ -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.
|
|
@ -1,6 +1,6 @@
|
||||||
export type Settings = {
|
export type Settings = {
|
||||||
[ key: string ]: unknown;
|
[ key: string ]: unknown;
|
||||||
} & {
|
} & { siteUrl?: string; shopUrl?: string } & {
|
||||||
general?: {
|
general?: {
|
||||||
[ key: string ]: string;
|
[ key: string ]: string;
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,12 +29,14 @@ export type CongratsProps = {
|
||||||
isWooExpress: boolean;
|
isWooExpress: boolean;
|
||||||
completeSurvey: () => void;
|
completeSurvey: () => void;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
|
siteIsShowingCachedContent: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Congrats = ( {
|
export const Congrats = ( {
|
||||||
hasCompleteSurvey,
|
hasCompleteSurvey,
|
||||||
isWooExpress,
|
isWooExpress,
|
||||||
completeSurvey,
|
completeSurvey,
|
||||||
|
siteIsShowingCachedContent,
|
||||||
children,
|
children,
|
||||||
}: CongratsProps ) => {
|
}: CongratsProps ) => {
|
||||||
const copyLink = __( 'Copy link', 'woocommerce' );
|
const copyLink = __( 'Copy link', 'woocommerce' );
|
||||||
|
@ -116,13 +118,39 @@ export const Congrats = ( {
|
||||||
</div>
|
</div>
|
||||||
<div className="woocommerce-launch-store__congrats-content">
|
<div className="woocommerce-launch-store__congrats-content">
|
||||||
<h1 className="woocommerce-launch-store__congrats-heading">
|
<h1 className="woocommerce-launch-store__congrats-heading">
|
||||||
{ __(
|
{ siteIsShowingCachedContent
|
||||||
|
? __(
|
||||||
|
'Congratulations! Your store will launch soon',
|
||||||
|
'woocommerce'
|
||||||
|
)
|
||||||
|
: __(
|
||||||
'Congratulations! Your store is now live',
|
'Congratulations! Your store is now live',
|
||||||
'woocommerce'
|
'woocommerce'
|
||||||
) }
|
) }
|
||||||
</h1>
|
</h1>
|
||||||
<h2 className="woocommerce-launch-store__congrats-subheading">
|
<h2 className="woocommerce-launch-store__congrats-subheading">
|
||||||
|
{ siteIsShowingCachedContent
|
||||||
|
? createInterpolateElement(
|
||||||
|
__(
|
||||||
|
'It’ll 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.",
|
"You've successfully launched your store and are ready to start selling! We can't wait to see your business grow.",
|
||||||
'woocommerce'
|
'woocommerce'
|
||||||
) }
|
) }
|
||||||
|
|
|
@ -43,6 +43,9 @@ export const LaunchYourStoreSuccess = ( props: MainContentComponentProps ) => {
|
||||||
}
|
}
|
||||||
isWooExpress={ isWooExpress() }
|
isWooExpress={ isWooExpress() }
|
||||||
completeSurvey={ completeSurvey }
|
completeSurvey={ completeSurvey }
|
||||||
|
siteIsShowingCachedContent={
|
||||||
|
props.context.siteIsShowingCachedContent
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<h2 className="woocommerce-launch-store__congrats-main-actions-title">
|
<h2 className="woocommerce-launch-store__congrats-main-actions-title">
|
||||||
{ __( "What's next?", 'woocommerce' ) }
|
{ __( "What's next?", 'woocommerce' ) }
|
||||||
|
|
|
@ -99,6 +99,9 @@
|
||||||
letter-spacing: -0.1px;
|
letter-spacing: -0.1px;
|
||||||
margin: 4px 0 0;
|
margin: 4px 0 0;
|
||||||
max-width: 560px;
|
max-width: 560px;
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.woocommerce-launch-store__congrats-main-actions-title {
|
.woocommerce-launch-store__congrats-main-actions-title {
|
||||||
|
|
|
@ -27,6 +27,7 @@ export type MainContentMachineContext = {
|
||||||
allTasklists: TaskListType[];
|
allTasklists: TaskListType[];
|
||||||
activePlugins: string[];
|
activePlugins: string[];
|
||||||
};
|
};
|
||||||
|
siteIsShowingCachedContent: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MainContentComponentProps = LaunchYourStoreComponentProps & {
|
export type MainContentComponentProps = LaunchYourStoreComponentProps & {
|
||||||
|
@ -34,6 +35,7 @@ export type MainContentComponentProps = LaunchYourStoreComponentProps & {
|
||||||
};
|
};
|
||||||
export type MainContentMachineEvents =
|
export type MainContentMachineEvents =
|
||||||
| { type: 'SHOW_LAUNCH_STORE_SUCCESS' }
|
| { type: 'SHOW_LAUNCH_STORE_SUCCESS' }
|
||||||
|
| { type: 'SHOW_LAUNCH_STORE_PENDING_CACHE' }
|
||||||
| { type: 'EXTERNAL_URL_UPDATE' }
|
| { type: 'EXTERNAL_URL_UPDATE' }
|
||||||
| { type: 'SHOW_LOADING' }
|
| { type: 'SHOW_LOADING' }
|
||||||
| congratsEvents;
|
| congratsEvents;
|
||||||
|
@ -54,6 +56,9 @@ export const mainContentMachine = setup( {
|
||||||
) => {
|
) => {
|
||||||
updateQueryParams( params );
|
updateQueryParams( params );
|
||||||
},
|
},
|
||||||
|
assignSiteCachedStatus: assign( {
|
||||||
|
siteIsShowingCachedContent: true,
|
||||||
|
} ),
|
||||||
},
|
},
|
||||||
guards: {
|
guards: {
|
||||||
hasContentLocation: (
|
hasContentLocation: (
|
||||||
|
@ -78,6 +83,7 @@ export const mainContentMachine = setup( {
|
||||||
allTasklists: [],
|
allTasklists: [],
|
||||||
activePlugins: [],
|
activePlugins: [],
|
||||||
},
|
},
|
||||||
|
siteIsShowingCachedContent: false,
|
||||||
},
|
},
|
||||||
invoke: {
|
invoke: {
|
||||||
id: 'contentQueryParamListener',
|
id: 'contentQueryParamListener',
|
||||||
|
@ -149,6 +155,10 @@ export const mainContentMachine = setup( {
|
||||||
SHOW_LAUNCH_STORE_SUCCESS: {
|
SHOW_LAUNCH_STORE_SUCCESS: {
|
||||||
target: '#launchStoreSuccess',
|
target: '#launchStoreSuccess',
|
||||||
},
|
},
|
||||||
|
SHOW_LAUNCH_STORE_PENDING_CACHE: {
|
||||||
|
actions: [ 'assignSiteCachedStatus' ],
|
||||||
|
target: '#launchStoreSuccess',
|
||||||
|
},
|
||||||
SHOW_LOADING: {
|
SHOW_LOADING: {
|
||||||
target: '#loading',
|
target: '#loading',
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,12 +9,18 @@ import {
|
||||||
fromPromise,
|
fromPromise,
|
||||||
assign,
|
assign,
|
||||||
spawnChild,
|
spawnChild,
|
||||||
|
enqueueActions,
|
||||||
} from 'xstate5';
|
} from 'xstate5';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { getQuery, navigateTo } from '@woocommerce/navigation';
|
import { getQuery, navigateTo } from '@woocommerce/navigation';
|
||||||
import { OPTIONS_STORE_NAME, TaskListType, TaskType } from '@woocommerce/data';
|
import {
|
||||||
import { dispatch } from '@wordpress/data';
|
OPTIONS_STORE_NAME,
|
||||||
|
SETTINGS_STORE_NAME,
|
||||||
|
TaskListType,
|
||||||
|
TaskType,
|
||||||
|
} from '@woocommerce/data';
|
||||||
|
import { dispatch, resolveSelect } from '@wordpress/data';
|
||||||
import { recordEvent } from '@woocommerce/tracks';
|
import { recordEvent } from '@woocommerce/tracks';
|
||||||
import apiFetch from '@wordpress/api-fetch';
|
import apiFetch from '@wordpress/api-fetch';
|
||||||
|
|
||||||
|
@ -44,6 +50,7 @@ export type SidebarMachineContext = {
|
||||||
launchStoreError?: {
|
launchStoreError?: {
|
||||||
message: string;
|
message: string;
|
||||||
};
|
};
|
||||||
|
siteIsShowingCachedContent?: boolean;
|
||||||
};
|
};
|
||||||
export type SidebarComponentProps = LaunchYourStoreComponentProps & {
|
export type SidebarComponentProps = LaunchYourStoreComponentProps & {
|
||||||
context: SidebarMachineContext;
|
context: SidebarMachineContext;
|
||||||
|
@ -81,6 +88,64 @@ const getTestOrderCount = async () => {
|
||||||
return result.count;
|
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 ( {
|
const deleteTestOrders = async ( {
|
||||||
input,
|
input,
|
||||||
}: {
|
}: {
|
||||||
|
@ -154,6 +219,10 @@ export const sidebarMachine = setup( {
|
||||||
( { context } ) => context.mainContentMachineRef,
|
( { context } ) => context.mainContentMachineRef,
|
||||||
{ type: 'SHOW_LAUNCH_STORE_SUCCESS' }
|
{ type: 'SHOW_LAUNCH_STORE_SUCCESS' }
|
||||||
),
|
),
|
||||||
|
showLaunchStorePendingCache: sendTo(
|
||||||
|
( { context } ) => context.mainContentMachineRef,
|
||||||
|
{ type: 'SHOW_LAUNCH_STORE_PENDING_CACHE' }
|
||||||
|
),
|
||||||
showLoadingPage: sendTo(
|
showLoadingPage: sendTo(
|
||||||
( { context } ) => context.mainContentMachineRef,
|
( { context } ) => context.mainContentMachineRef,
|
||||||
{ type: 'SHOW_LOADING' }
|
{ type: 'SHOW_LOADING' }
|
||||||
|
@ -189,6 +258,11 @@ export const sidebarMachine = setup( {
|
||||||
success
|
success
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
recordStoreLaunchCachedContentDetected: () => {
|
||||||
|
recordEvent(
|
||||||
|
'launch_your_store_hub_store_launch_cached_content_detected'
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
guards: {
|
guards: {
|
||||||
hasSidebarLocation: (
|
hasSidebarLocation: (
|
||||||
|
@ -203,11 +277,15 @@ export const sidebarMachine = setup( {
|
||||||
'woocommerce-payments'
|
'woocommerce-payments'
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
siteIsShowingCachedContent: ( { context } ) => {
|
||||||
|
return !! context.siteIsShowingCachedContent;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
actors: {
|
actors: {
|
||||||
sidebarQueryParamListener,
|
sidebarQueryParamListener,
|
||||||
getTasklist: fromPromise( getLysTasklist ),
|
getTasklist: fromPromise( getLysTasklist ),
|
||||||
getTestOrderCount: fromPromise( getTestOrderCount ),
|
getTestOrderCount: fromPromise( getTestOrderCount ),
|
||||||
|
getSiteCachedStatus: fromPromise( getSiteCachedStatus ),
|
||||||
updateLaunchStoreOptions: fromPromise( launchStoreAction ),
|
updateLaunchStoreOptions: fromPromise( launchStoreAction ),
|
||||||
deleteTestOrders: fromPromise( deleteTestOrders ),
|
deleteTestOrders: fromPromise( deleteTestOrders ),
|
||||||
fetchCongratsData,
|
fetchCongratsData,
|
||||||
|
@ -317,13 +395,13 @@ export const sidebarMachine = setup( {
|
||||||
{
|
{
|
||||||
src: 'updateLaunchStoreOptions',
|
src: 'updateLaunchStoreOptions',
|
||||||
onDone: {
|
onDone: {
|
||||||
target: '#storeLaunchSuccessful',
|
|
||||||
actions: [
|
actions: [
|
||||||
{
|
{
|
||||||
type: 'recordStoreLaunchResults',
|
type: 'recordStoreLaunchResults',
|
||||||
params: { success: true },
|
params: { success: true },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
target: 'checkingForCachedContent',
|
||||||
},
|
},
|
||||||
onError: {
|
onError: {
|
||||||
actions: [
|
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: {
|
storeLaunchSuccessful: {
|
||||||
|
@ -373,7 +468,18 @@ export const sidebarMachine = setup( {
|
||||||
content: 'launch-store-success',
|
content: 'launch-store-success',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ type: 'showLaunchStoreSuccessPage' },
|
enqueueActions( ( { check, enqueue } ) => {
|
||||||
|
if ( check( 'siteIsShowingCachedContent' ) ) {
|
||||||
|
enqueue( {
|
||||||
|
type: 'showLaunchStorePendingCache',
|
||||||
|
} );
|
||||||
|
enqueue( {
|
||||||
|
type: 'recordStoreLaunchCachedContentDetected',
|
||||||
|
} );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
enqueue( { type: 'showLaunchStoreSuccessPage' } );
|
||||||
|
} ),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
openExternalUrl: {
|
openExternalUrl: {
|
||||||
|
|
|
@ -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.
|
|
@ -52,17 +52,27 @@ class ComingSoonRequestHandler {
|
||||||
|
|
||||||
$coming_soon_template = get_query_template( 'coming-soon' );
|
$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();
|
get_header();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
add_action(
|
||||||
|
'wp_head',
|
||||||
|
function () {
|
||||||
|
echo "<meta name='woo-coming-soon-page' content='yes'>";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
include $coming_soon_template;
|
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();
|
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.
|
// Since we've already rendered a template, return null to ensure no other template is rendered.
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue