Skip to content

Commit 11a4562

Browse files
committed
Enable hybrid mode and update routing logic for SFRA integration. Adjusted SSR and app configuration for private client usage and passkey login. Updated API proxy settings for staging environment.
1 parent e7706b5 commit 11a4562

File tree

4 files changed

+81
-18
lines changed

4 files changed

+81
-18
lines changed

packages/template-retail-react-app/app/components/_app-config/index.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,10 @@ const AppConfig = ({children, locals = {}}) => {
107107
defaultDnt={DEFAULT_DNT_STATE}
108108
// Set 'enablePWAKitPrivateClient' to true to use SLAS private client login flows.
109109
// Make sure to also enable useSLASPrivateClient in ssr.js when enabling this setting.
110-
enablePWAKitPrivateClient={false}
110+
enablePWAKitPrivateClient={true}
111111
privateClientProxyEndpoint={slasPrivateClientProxyEndpoint}
112112
// Uncomment 'hybridAuthEnabled' if the current site has Hybrid Auth enabled. Do NOT set this flag for hybrid storefronts using Plugin SLAS.
113-
// hybridAuthEnabled={true}
113+
hybridAuthEnabled={true}
114114
logger={createLogger({packageName: 'commerce-sdk-react'})}
115115
>
116116
<MultiSiteProvider site={locals.site} locale={locals.locale} buildUrl={locals.buildUrl}>

packages/template-retail-react-app/app/routes.jsx

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
import React from 'react'
1616
import loadable from '@loadable/component'
1717
import {getConfig} from '@salesforce/pwa-kit-runtime/utils/ssr-config'
18-
18+
import {withRouter} from 'react-router-dom'
19+
import {useEffect} from 'react'
1920
// Components
2021
import {Skeleton} from '@salesforce/retail-react-app/app/components/shared/ui'
2122
import {configureRoutes} from '@salesforce/retail-react-app/app/utils/routes-utils'
@@ -123,13 +124,17 @@ export const routes = [
123124

124125
export default () => {
125126
const config = getConfig()
127+
const enableHybrid = config?.app?.enableHybrid
126128
const loginConfig = config?.app?.login
127129
const resetPasswordLandingPath = loginConfig?.resetPassword?.landingPath
128130
const socialLoginEnabled = loginConfig?.social?.enabled
129131
const socialRedirectURI = loginConfig?.social?.redirectURI
130132
const passwordlessLoginEnabled = loginConfig?.passwordless?.enabled
131133
const passwordlessLoginLandingPath = loginConfig?.passwordless?.landingPath
132134

135+
// Paths handled by SFRA in hybrid mode
136+
const hybridPaths = ['/cart', '/checkout', '/checkout/confirmation/:orderNo']
137+
133138
// Add dynamic routes conditionally (only if features are enabled and paths are defined)
134139
const dynamicRoutes = [
135140
resetPasswordLandingPath && {
@@ -151,11 +156,53 @@ export default () => {
151156
}
152157
].filter(Boolean)
153158

154-
const allRoutes = configureRoutes([...routes, ...dynamicRoutes], config, {
155-
ignoredRoutes: ['/callback'],
156-
fuzzyPathMatching: true
157-
})
159+
const allRoutes = configureRoutes(
160+
[...routes, ...dynamicRoutes].filter(
161+
(r) => !enableHybrid || !hybridPaths.includes(r.path)
162+
),
163+
config,
164+
{ignoredRoutes: ['/callback'], fuzzyPathMatching: true}
165+
)
158166

159167
// Add catch-all route at the end so it doesn't match before dynamic routes
160-
return [...allRoutes, {path: '*', component: PageNotFound}]
168+
return [
169+
...allRoutes,
170+
{
171+
path: '*',
172+
component: withRouter((props) => {
173+
const {location} = props
174+
const urlParams = new URLSearchParams(location.search)
175+
176+
useEffect(() => {
177+
if (enableHybrid && !urlParams.has('redirected')) {
178+
// Redirect client-side navigations directly to SFRA
179+
const sfccOrigin = getConfig()?.app?.sfccOrigin
180+
const siteId = getConfig()?.app?.defaultSite || 'RefArchGlobal'
181+
// Strip the PWA Kit site/locale prefix (e.g. /global/en-GB) from the path
182+
const pwaPath = location.pathname.replace(
183+
/^\/[^/]+\/[^/]+\//,
184+
'/'
185+
)
186+
const isLocalhost = window.location.hostname === 'localhost'
187+
const target =
188+
sfccOrigin && !isLocalhost
189+
? `${sfccOrigin}/s/${siteId}${pwaPath}`
190+
: `/s/${siteId}${pwaPath}`
191+
window.location.replace(target)
192+
return
193+
}
194+
const newURL = new URL(window.location)
195+
if (!urlParams.has('redirected')) {
196+
newURL.searchParams.append('redirected', '1')
197+
window.location.href = newURL
198+
}
199+
}, [window.location.href])
200+
201+
if (urlParams.has('redirected')) {
202+
return <PageNotFound {...props} />
203+
}
204+
return null
205+
})
206+
}
207+
]
161208
}

packages/template-retail-react-app/app/ssr.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const options = {
5151
// Set this to false if using a SLAS public client
5252
// When setting this to true, make sure to also set the PWA_KIT_SLAS_CLIENT_SECRET
5353
// environment variable as this endpoint will return HTTP 501 if it is not set
54-
useSLASPrivateClient: false,
54+
useSLASPrivateClient: true,
5555

5656
// If you wish to use additional SLAS endpoints that require private clients,
5757
// customize this regex to include the additional endpoints the custom SLAS
@@ -79,7 +79,7 @@ const options = {
7979
// HYBRID PROXY REQUIREMENT:
8080
// - Hybrid Proxy requires this to be 'true' for SFCC session management to work properly
8181
// - Only enable Hybrid Proxy in development environments, never in production
82-
localAllowCookies: false,
82+
localAllowCookies: true,
8383

8484
// Hybrid Proxy configuration for local development and MRT to ODS connection testing.
8585
//
@@ -94,10 +94,14 @@ const options = {
9494
// If this is enabled, the Hybrid Proxy will be enabled to proxy requests to the SFCC instance.
9595
// 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.
9696
// Refer to https://developer.salesforce.com/docs/commerce/commerce-api/guide/hybrid-authentication.html for more details.
97-
enabled: false,
97+
enabled: true,
9898

9999
// The origin of the SFCC instance (i.e. the instance that is being proxied to which hosts the storefront).
100-
sfccOrigin: 'https://zzrf-001.dx.commercecloud.salesforce.com',
100+
// Use the direct demandware.net hostname here (not the CDN/eCDN hostname) so the proxy
101+
// can reach SFCC server-to-server without hitting Cloudflare Zero Trust.
102+
// The Location-header rewriter in hybrid-proxy.js handles redirects to any hostname
103+
// (including the CDN hostname tbdq-stg.cc-bm-dev.net) by rewriting them back through the proxy.
104+
sfccOrigin: 'https://staging-realm26-qa223.demandware.net',
101105

102106
// The MRT rules to apply to the hybrid proxy.
103107
// 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.

packages/template-retail-react-app/config/default.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,13 @@ module.exports = {
4848
landingPath: '/reset-password-landing'
4949
},
5050
passkey: {
51-
enabled: false,
52-
callbackURI: process.env.PASSKEY_CALLBACK_URI
51+
enabled: true,
52+
mode: 'callback',
53+
callbackURI: 'https://webhook.site/1b592264-a9b1-4d75-a892-cf68fed334f1'
5354
}
5455
},
56+
enableHybrid: true,
57+
sfccOrigin: 'https://staging-realm26-qa223.demandware.net',
5558
defaultSite: 'RefArchGlobal',
5659
siteAliases: {
5760
RefArch: 'us',
@@ -61,9 +64,9 @@ module.exports = {
6164
commerceAPI: {
6265
proxyPath: `/mobify/proxy/api`,
6366
parameters: {
64-
clientId: 'c9c45bfd-0ed3-4aa2-9971-40f88962b836',
65-
organizationId: 'f_ecom_zzrf_001',
66-
shortCode: '8o7m175y',
67+
clientId: '472f318c-8628-4b8d-81cf-b48c2352e9e5',
68+
organizationId: 'f_ecom_tbdq_stg',
69+
shortCode: 'sandbox-001',
6770
siteId: 'RefArchGlobal'
6871
}
6972
},
@@ -111,10 +114,19 @@ module.exports = {
111114
ssrParameters: {
112115
ssrFunctionNodeVersion: '24.x',
113116
proxyConfigs: [
117+
// {
118+
// host: 'kv7kzm78.api.commercecloud.salesforce.com',
119+
// path: 'api'
120+
// },
121+
// For bjmk_dev, tbdq_stg
114122
{
115-
host: 'kv7kzm78.api.commercecloud.salesforce.com',
123+
host: 'sandbox-001.api.commercecloud.salesforce.com',
116124
path: 'api'
117125
},
126+
{
127+
host: 'staging-realm26-qa223.demandware.net',
128+
path: 'dwrestatic'
129+
},
118130
{
119131
host: 'zzrf-001.dx.commercecloud.salesforce.com',
120132
path: 'ocapi'

0 commit comments

Comments
 (0)