diff --git a/packages/template-retail-react-app/app/components/_app-config/index.jsx b/packages/template-retail-react-app/app/components/_app-config/index.jsx index 7880c28341..7c51f3a318 100644 --- a/packages/template-retail-react-app/app/components/_app-config/index.jsx +++ b/packages/template-retail-react-app/app/components/_app-config/index.jsx @@ -107,10 +107,10 @@ const AppConfig = ({children, locals = {}}) => { defaultDnt={DEFAULT_DNT_STATE} // Set 'enablePWAKitPrivateClient' to true to use SLAS private client login flows. // Make sure to also enable useSLASPrivateClient in ssr.js when enabling this setting. - enablePWAKitPrivateClient={false} + enablePWAKitPrivateClient={true} privateClientProxyEndpoint={slasPrivateClientProxyEndpoint} // Uncomment 'hybridAuthEnabled' if the current site has Hybrid Auth enabled. Do NOT set this flag for hybrid storefronts using Plugin SLAS. - // hybridAuthEnabled={true} + hybridAuthEnabled={true} logger={createLogger({packageName: 'commerce-sdk-react'})} > diff --git a/packages/template-retail-react-app/app/routes.jsx b/packages/template-retail-react-app/app/routes.jsx index 180d0e7769..d06fc50434 100644 --- a/packages/template-retail-react-app/app/routes.jsx +++ b/packages/template-retail-react-app/app/routes.jsx @@ -12,9 +12,11 @@ // we don't want it to count toward coverage until we figure out how to cover the `functions` // metric for this file in its test. -import React from 'react' +import React, {useEffect} from 'react' +import {withRouter} from 'react-router-dom' import loadable from '@loadable/component' import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config' +import useMultiSite from '@salesforce/retail-react-app/app/hooks/use-multi-site' // Components import {Skeleton} from '@salesforce/retail-react-app/app/components/shared/ui' @@ -121,8 +123,12 @@ export const routes = [ } ] +// Remove SFRA/SiteGenesis routes from PWA Kit +const ecomRoutes = ['/cart', '/checkout', '*'] + export default () => { const config = getConfig() + const enableHybrid = config?.app?.enableHybrid const loginConfig = config?.app?.login const resetPasswordLandingPath = loginConfig?.resetPassword?.landingPath const socialLoginEnabled = loginConfig?.social?.enabled @@ -151,11 +157,46 @@ export default () => { } ].filter(Boolean) - const allRoutes = configureRoutes([...routes, ...dynamicRoutes], config, { - ignoredRoutes: ['/callback'], - fuzzyPathMatching: true - }) + const allBaseRoutes = [...routes, ...dynamicRoutes] + + const hybridRoutes = [ + ...allBaseRoutes.filter((route) => !ecomRoutes.includes(route.path)), + { + path: '*', + component: withRouter((props) => { + const {location} = props + const urlParams = new URLSearchParams(location.search) + const {site} = useMultiSite() + const siteId = site && site.id ? site.id : config?.app?.defaultSite + + if (typeof window !== 'undefined') { + useEffect(() => { + const newURL = new URL(window.location) + if (!urlParams.has('redirected')) { + newURL.searchParams.append('redirected', '1') + newURL.pathname = `/s/${siteId}/${window.location.pathname + .split('/') + .slice(2) + .join('/')}` + window.location.replace(newURL) + } + }, [window.location.href]) + } - // Add catch-all route at the end so it doesn't match before dynamic routes - return [...allRoutes, {path: '*', component: PageNotFound}] + if (urlParams.has('redirected')) { + return + } + + return null + }) + } + ] + + // Only use these routes if we are in hybrid mode otherwise use defaults + // This is driven via the config and env variables + const routesToConfigure = enableHybrid ? hybridRoutes : allBaseRoutes + + return configureRoutes(routesToConfigure, config, { + ignoredRoutes: ['/callback', '*'] + }) } diff --git a/packages/template-retail-react-app/app/ssr.js b/packages/template-retail-react-app/app/ssr.js index 98bb6b9aee..41ffaa3b20 100644 --- a/packages/template-retail-react-app/app/ssr.js +++ b/packages/template-retail-react-app/app/ssr.js @@ -51,7 +51,7 @@ const options = { // Set this to false if using a SLAS public client // When setting this to true, make sure to also set the PWA_KIT_SLAS_CLIENT_SECRET // environment variable as this endpoint will return HTTP 501 if it is not set - useSLASPrivateClient: false, + useSLASPrivateClient: true, // If you wish to use additional SLAS endpoints that require private clients, // customize this regex to include the additional endpoints the custom SLAS @@ -79,7 +79,7 @@ const options = { // HYBRID PROXY REQUIREMENT: // - Hybrid Proxy requires this to be 'true' for SFCC session management to work properly // - Only enable Hybrid Proxy in development environments, never in production - localAllowCookies: false, + localAllowCookies: true, // Hybrid Proxy configuration for local development and MRT to ODS connection testing. // @@ -94,10 +94,14 @@ const options = { // If this is enabled, the Hybrid Proxy will be enabled to proxy requests to the SFCC instance. // IMPORTANT: This should only be used for local development. For production, this should be disabled and use eCDN to direct requests to the SFCC instance. // Refer to https://developer.salesforce.com/docs/commerce/commerce-api/guide/hybrid-authentication.html for more details. - enabled: false, + enabled: true, // The origin of the SFCC instance (i.e. the instance that is being proxied to which hosts the storefront). - sfccOrigin: 'https://zzrf-001.dx.commercecloud.salesforce.com', + // Use the direct demandware.net hostname here (not the CDN/eCDN hostname) so the proxy + // can reach SFCC server-to-server without hitting Cloudflare Zero Trust. + // The Location-header rewriter in hybrid-proxy.js handles redirects to any hostname + // (including the CDN hostname tbdq-stg.cc-bm-dev.net) by rewriting them back through the proxy. + sfccOrigin: 'https://staging-realm26-qa223.demandware.net', // The MRT rules to apply to the hybrid proxy. // These rules determine which requests are handled by PWA Kit (MRT) vs proxied to SFCC. The same rules should be used in the eCDN rules for the same requests. diff --git a/packages/template-retail-react-app/config/default.js b/packages/template-retail-react-app/config/default.js index b449fcd443..1f37adc09b 100644 --- a/packages/template-retail-react-app/config/default.js +++ b/packages/template-retail-react-app/config/default.js @@ -48,10 +48,13 @@ module.exports = { landingPath: '/reset-password-landing' }, passkey: { - enabled: false, - callbackURI: process.env.PASSKEY_CALLBACK_URI + enabled: true, + mode: 'callback', + callbackURI: 'https://webhook.site/1b592264-a9b1-4d75-a892-cf68fed334f1' } }, + enableHybrid: true, + sfccOrigin: 'https://staging-realm26-qa223.demandware.net', defaultSite: 'RefArchGlobal', siteAliases: { RefArch: 'us', @@ -61,9 +64,9 @@ module.exports = { commerceAPI: { proxyPath: `/mobify/proxy/api`, parameters: { - clientId: 'c9c45bfd-0ed3-4aa2-9971-40f88962b836', - organizationId: 'f_ecom_zzrf_001', - shortCode: '8o7m175y', + clientId: '472f318c-8628-4b8d-81cf-b48c2352e9e5', + organizationId: 'f_ecom_tbdq_stg', + shortCode: 'sandbox-001', siteId: 'RefArchGlobal' } }, @@ -111,10 +114,19 @@ module.exports = { ssrParameters: { ssrFunctionNodeVersion: '24.x', proxyConfigs: [ + // { + // host: 'kv7kzm78.api.commercecloud.salesforce.com', + // path: 'api' + // }, + // For bjmk_dev, tbdq_stg { - host: 'kv7kzm78.api.commercecloud.salesforce.com', + host: 'sandbox-001.api.commercecloud.salesforce.com', path: 'api' }, + { + host: 'staging-realm26-qa223.demandware.net', + path: 'dwrestatic' + }, { host: 'zzrf-001.dx.commercecloud.salesforce.com', path: 'ocapi'