@faststore/core 4.4.0-dev.2 → 4.4.0-dev.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/.turbo/turbo-generate.log +3 -3
  2. package/.turbo/turbo-test.log +45 -42
  3. package/CHANGELOG.md +12 -0
  4. package/package.json +6 -6
  5. package/src/components/account/Drawer/OrganizationDrawer/OrganizationDrawerBody.tsx +1 -1
  6. package/src/components/account/Menu/Menu.tsx +2 -1
  7. package/src/components/account/orders/ListOrders/FilterSlider/FilterSlider.tsx +5 -1
  8. package/src/components/account/orders/ListOrders/ListOrders.tsx +8 -3
  9. package/src/components/account/orders/ListOrders/ListOrdersTable/ListOrdersTable.tsx +6 -3
  10. package/src/components/account/orders/ListOrders/SelectedTags/SelectedTags.tsx +2 -2
  11. package/src/components/account/orders/OrderDetails/OrderDetailsHeader.tsx +6 -1
  12. package/src/components/account/utils/useFormatPrice.ts +3 -2
  13. package/src/components/ui/Link/Link.tsx +6 -0
  14. package/src/experimental/index.ts +3 -0
  15. package/src/experimental/myAccountServerSideProps.ts +6 -2
  16. package/src/pages/pvt/account/404.tsx +5 -1
  17. package/src/pages/pvt/account/[...unknown].tsx +6 -2
  18. package/src/pages/pvt/account/index.tsx +5 -4
  19. package/src/pages/pvt/account/profile.tsx +2 -1
  20. package/src/pages/pvt/account/user-details.tsx +4 -3
  21. package/src/proxy.ts +36 -0
  22. package/src/sdk/product/useLocalizedVariables.ts +14 -1
  23. package/src/sdk/session/index.ts +9 -6
  24. package/src/sdk/session/initialSession.ts +31 -46
  25. package/src/utils/localization/localizeRedirectDestination.ts +66 -0
  26. package/src/utils/localization/withLocaleValidation.ts +0 -6
  27. package/test/proxy.localization.test.ts +122 -0
  28. package/test/sdk/session/reconcileSessionLocale.browser.test.ts +199 -0
  29. package/test/sdk/session/reconcileSessionLocale.disabled.browser.test.ts +38 -0
  30. package/test/utils/localization/localizeRedirectDestination.test.ts +176 -0
  31. package/test/sdk/session/installLocaleCorrector.browser.test.ts +0 -208
@@ -1,9 +1,9 @@
1
1
 
2
- > @faststore/core@4.4.0-dev.1 generate /home/runner/work/faststore/faststore/packages/core
2
+ > @faststore/core@4.4.0-dev.3 generate /home/runner/work/faststore/faststore/packages/core
3
3
  > pnpm run gen-types && pnpm run cache-graphql
4
4
 
5
5
 
6
- > @faststore/core@4.4.0-dev.1 gen-types /home/runner/work/faststore/faststore/packages/core
6
+ > @faststore/core@4.4.0-dev.3 gen-types /home/runner/work/faststore/faststore/packages/core
7
7
  > node ../cli/bin/run generate-types .
8
8
 
9
9
  [STARTED] Parse Configuration
@@ -19,7 +19,7 @@
19
19
  [COMPLETED] Generate to /home/runner/work/faststore/faststore/packages/core/@generated/
20
20
  [COMPLETED] Generate outputs
21
21
 
22
- > @faststore/core@4.4.0-dev.1 cache-graphql /home/runner/work/faststore/faststore/packages/core
22
+ > @faststore/core@4.4.0-dev.3 cache-graphql /home/runner/work/faststore/faststore/packages/core
23
23
  > node ../cli/bin/run cache-graphql --config=./discovery.config.default.js --queries=./@generated/persisted-documents.json
24
24
 
25
25
  [Info] - Config file location: /home/runner/work/faststore/faststore/packages/core/discovery.config.default.js
@@ -1,20 +1,20 @@
1
1
 
2
- > @faststore/core@4.4.0-dev.1 test /home/runner/work/faststore/faststore/packages/core
2
+ > @faststore/core@4.4.0-dev.3 test /home/runner/work/faststore/faststore/packages/core
3
3
  > vitest run
4
4
 
5
5
 
6
6
   RUN  v4.0.7 /home/runner/work/faststore/faststore/packages/core
7
7
 
8
- ✓  browser  test/sdk/session/getInitialSession.browser.test.ts (6 tests) 32ms
9
- ✓  browser  test/sdk/session/installLocaleCorrector.browser.test.ts (7 tests) 59ms
8
+ ✓  browser  test/sdk/session/getInitialSession.browser.test.ts (6 tests) 41ms
9
+ ✓  browser  test/sdk/session/reconcileSessionLocale.browser.test.ts (5 tests) 25ms
10
+ ✓  browser  test/utils/isLocalHost.browser.test.ts (3 tests) 15ms
10
11
  stderr | test/sdk/localization/store-url.browser.test.ts
11
12
  Error in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
12
13
  at validateCart (/home/runner/work/faststore/faststore/packages/core/src/sdk/cart/index.ts:119:27)
13
14
  at onValidate (/home/runner/work/faststore/faststore/packages/core/src/sdk/useStore.ts:18:20)
14
- at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:353:23)
15
+ at a (/home/runner/work/faststore/faststore/packages/sdk/dist/es/index.mjs:354:23)
15
16
   at processTicksAndRejections (node:internal/process/task_queues:103:5)
16
17
 
17
- ✓  browser  test/utils/isLocalHost.browser.test.ts (3 tests) 8ms
18
18
  stderr | test/pages/password-protection.browser.test.tsx > PasswordProtectionLogin > posts the password and redirects to the requested return path
19
19
  Warning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
20
20
 
@@ -244,19 +244,19 @@ act(() => {
244
244
  This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
245
245
  at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
246
246
 
247
- ✓  browser  test/pages/password-protection.browser.test.tsx (6 tests) 1839ms
248
- ✓ renders the password protection form  848ms
249
- ✓  node  test/utils/localization/bindingPaths.test.ts (71 tests) 33ms
250
- ✓  browser  test/sdk/localization/store-url.browser.test.ts (3 tests) 21ms
251
- ✓  node  test/utils/match-url.test.ts (10 tests) 29ms
252
- ✓  node  test/server/password-protection-service.test.ts (22 tests) 164ms
253
- ✓  node  test/sdk/localization/bindingSelector.test.ts (18 tests) 34ms
254
- ✓  node  test/pages/api/unlock.test.ts (15 tests) 579ms
255
- ✓ returns 405 for non-POST requests  366ms
247
+ ✓  browser  test/pages/password-protection.browser.test.tsx (6 tests) 1653ms
248
+ ✓ renders the password protection form  724ms
249
+ ✓  browser  test/sdk/localization/store-url.browser.test.ts (3 tests) 14ms
250
+ ✓  node  test/utils/localization/bindingPaths.test.ts (71 tests) 115ms
251
+ ✓  node  test/server/password-protection-service.test.ts (22 tests) 122ms
252
+ ✓  browser  test/sdk/session/reconcileSessionLocale.disabled.browser.test.ts (1 test) 6ms
253
+ ✓  node  test/utils/match-url.test.ts (10 tests) 30ms
254
+ ✓  node  test/sdk/localization/bindingSelector.test.ts (18 tests) 32ms
255
+ ✓  node  test/pages/api/unlock.test.ts (15 tests) 846ms
256
+ ✓ returns 405 for non-POST requests  578ms
256
257
  stderr | test/components/search/SearchInputComponent.test.tsx
257
258
  Warning: forwardRef render functions accept exactly two parameters: props and ref. Did you forget to use the ref parameter?
258
259
 
259
- ✓  node  test/utils/cookieCacheBusting.test.ts (10 tests) 41ms
260
260
  stderr | test/components/search/SearchInputComponent.test.tsx > SearchInput (OES integration) > renders without crashing
261
261
  Warning: React does not recognize the `visibleDropdown` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `visibledropdown` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
262
262
  at div
@@ -317,16 +317,18 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
317
317
  at Suspense
318
318
  at Wrapper (/home/runner/work/faststore/faststore/packages/core/test/components/search/SearchInputComponent.test.tsx:106:20)
319
319
 
320
- ✓  node  test/components/search/SearchInputComponent.test.tsx (6 tests) 292ms
321
- ✓  node  test/sdk/localization/useBindingSelector.test.tsx (12 tests) 29ms
322
- ✓  node  test/sdk/search/useSearchHistory.test.ts (13 tests) 111ms
323
- ✓  node  test/utils/clearCookies.test.ts (20 tests) 113ms
324
- ✓  node  test/utils/multipleTemplates.test.ts (8 tests) 19ms
325
- ✓  node  test/sdk/orderEntry/useOrderEntryOperation.test.ts (8 tests) 139ms
320
+ ✓  node  test/components/search/SearchInputComponent.test.tsx (6 tests) 379ms
321
+ ✓  node  test/utils/cookieCacheBusting.test.ts (10 tests) 62ms
322
+ ✓  node  test/sdk/search/useSearchHistory.test.ts (13 tests) 289ms
323
+ ✓  node  test/sdk/localization/useBindingSelector.test.tsx (12 tests) 33ms
324
+ ✓  node  test/utils/clearCookies.test.ts (20 tests) 34ms
325
+ ✓  node  test/utils/multipleTemplates.test.ts (8 tests) 7ms
326
326
  stderr | test/sdk/account/useSetPassword.test.ts > useSetPassword > maps wrongcredentials error responses to the existing message
327
327
  Set password request failed: Bad Request
328
328
 
329
- ✓  node  test/sdk/account/useSetPassword.test.ts (6 tests) 99ms
329
+ ✓  node  test/sdk/account/useSetPassword.test.ts (6 tests) 52ms
330
+ ✓  node  test/utils/localization/localizeRedirectDestination.test.ts (11 tests) 5ms
331
+ ✓  node  test/sdk/orderEntry/useOrderEntryOperation.test.ts (8 tests) 45ms
330
332
  stderr | test/pages/api/graphql.test.ts > /api/graphql error status propagation > propagates the upstream 400 from a wrapped BadRequestError instead of 500
331
333
  Graphql execution returned with error: [
332
334
  {
@@ -345,6 +347,7 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
345
347
  stderr | test/pages/api/graphql.test.ts > /api/graphql error status propagation > propagates NotFoundError status
346
348
  Graphql execution returned with error: [ { message: 'nope', status: 404, type: 'NotFoundError' } ]
347
349
 
350
+ ✓  node  test/sdk/orderEntry/useOrderEntryUpload.test.ts (8 tests) 67ms
348
351
  stderr | test/pages/api/graphql.test.ts > /api/graphql error status propagation > propagates an unmapped upstream status (UnknownError 429)
349
352
  Graphql execution returned with error: [ { message: 'slow down', status: 429, type: 'UnknownError' } ]
350
353
 
@@ -373,30 +376,30 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
373
376
  { message: 'bad', status: 400, type: 'BadRequestError' }
374
377
  ]
375
378
 
376
- ✓  node  test/pages/api/graphql.test.ts (10 tests) 22ms
377
- ✓  node  test/sdk/orderEntry/useOrderEntryUpload.test.ts (8 tests) 48ms
378
- ✓  node  test/sdk/orderEntry/useOrderEntry.test.ts (8 tests) 40ms
379
- ✓  node  test/sdk/orderEntry/useOrderFormItems.test.ts (7 tests) 38ms
380
- ✓  node  test/server/webops-api.test.ts (9 tests) 20ms
381
- ✓  node  test/proxy.test.ts (4 tests) 31ms
382
- ✓  node  test/server/index.test.ts (7 tests) 900ms
383
- ✓ should handle options and execute  369ms
384
- ✓  node  test/server/cms/global.test.ts (3 tests) 6ms
385
- ✓  node  test/sdk/localization/store-url.test.ts (1 test) 6ms
379
+ ✓  node  test/pages/api/graphql.test.ts (10 tests) 35ms
380
+ ✓  node  test/proxy.localization.test.ts (5 tests) 67ms
381
+ ✓  node  test/sdk/orderEntry/useOrderEntry.test.ts (8 tests) 62ms
382
+ ✓  node  test/sdk/orderEntry/useOrderFormItems.test.ts (7 tests) 48ms
383
+ ✓  node  test/proxy.test.ts (4 tests) 68ms
384
+ ✓  node  test/server/webops-api.test.ts (9 tests) 22ms
385
+ ✓  node  test/server/index.test.ts (7 tests) 877ms
386
+ ✓ should return a valid merged GraphQL schema  319ms
387
+ ✓  node  test/server/cms/global.test.ts (3 tests) 5ms
386
388
  ✓  node  test/server/content/service.test.ts (5 tests) 5ms
389
+ ✓  node  test/sdk/localization/store-url.test.ts (1 test) 5ms
387
390
  ✓  node  test/utils/getRequestHostname.test.ts (12 tests) 6ms
388
- ✓  node  test/sdk/auth/useAuth.test.ts (5 tests) 41ms
389
- ✓  node  test/pages/api/preview.test.ts (2 tests) 8ms
391
+ ✓  node  test/sdk/auth/useAuth.test.ts (5 tests) 33ms
392
+ ✓  node  test/pages/api/preview.test.ts (2 tests) 10ms
390
393
  ✓  node  test/utils/validateSessionRefreshToken.test.ts (6 tests) 6ms
391
- ✓  node  test/components/search/SearchInput.test.ts (6 tests) 8ms
394
+ ✓  node  test/components/search/SearchInput.test.ts (6 tests) 11ms
392
395
  ✓  node  test/utils/unlockResponse.test.ts (11 tests) 5ms
393
- ✓  node  test/server/cms/index.test.ts (2 tests) 6ms
396
+ ✓  node  test/server/cms/index.test.ts (2 tests) 8ms
394
397
  ✓  node  test/utils/isLocalHost.test.ts (7 tests) 5ms
395
- ✓  node  test/utils/userOrderStatus.test.ts (3 tests) 4ms
396
- ✓  node  test/components/auth/ProfileChallenge.test.tsx (3 tests) 27ms
398
+ ✓  node  test/utils/userOrderStatus.test.ts (3 tests) 3ms
399
+ ✓  node  test/components/auth/ProfileChallenge.test.tsx (3 tests) 26ms
397
400
 
398
-  Test Files  38 passed (38)
399
-  Tests  363 passed (363)
400
-  Start at  14:16:16
401
-  Duration  25.18s (transform 6.88s, setup 0ms, collect 19.09s, tests 4.87s, environment 32.84s, prepare 1.03s)
401
+  Test Files  41 passed (41)
402
+  Tests  378 passed (378)
403
+  Start at  14:03:48
404
+  Duration  24.51s (transform 6.83s, setup 0ms, collect 18.67s, tests 5.18s, environment 30.97s, prepare 1.05s)
402
405
 
package/CHANGELOG.md CHANGED
@@ -3,6 +3,18 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [4.4.0-dev.4](https://github.com/vtex/faststore/compare/v4.4.0-dev.3...v4.4.0-dev.4) (2026-06-30)
7
+
8
+ ### Features
9
+
10
+ - add i18n support for /pvt/account navigation ([#3400](https://github.com/vtex/faststore/issues/3400)) ([695dd0e](https://github.com/vtex/faststore/commit/695dd0ee8e06e32ad76c23925c5e095740430f0f))
11
+
12
+ # [4.4.0-dev.3](https://github.com/vtex/faststore/compare/v4.4.0-dev.2...v4.4.0-dev.3) (2026-06-29)
13
+
14
+ ### Bug Fixes
15
+
16
+ - sync IS locale with URL and selectedFacets on navigation ([#3405](https://github.com/vtex/faststore/issues/3405)) ([90d644d](https://github.com/vtex/faststore/commit/90d644dcf7a232c3f2bea316658580b10108b502)), closes [#3401](https://github.com/vtex/faststore/issues/3401) [#3401](https://github.com/vtex/faststore/issues/3401)
17
+
6
18
  # [4.4.0-dev.2](https://github.com/vtex/faststore/compare/v4.4.0-dev.1...v4.4.0-dev.2) (2026-06-25)
7
19
 
8
20
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/core",
3
- "version": "4.4.0-dev.2",
3
+ "version": "4.4.0-dev.4",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -71,11 +71,11 @@
71
71
  "style-loader": "^3.3.1",
72
72
  "swr": "^2.2.5",
73
73
  "use-sync-external-store": "^1.6.0",
74
- "@faststore/diagnostics": "4.4.0-dev.2",
75
- "@faststore/api": "4.4.0-dev.2",
76
- "@faststore/lighthouse": "4.4.0-dev.2",
77
- "@faststore/sdk": "4.4.0-dev.2",
78
- "@faststore/ui": "4.4.0-dev.2"
74
+ "@faststore/diagnostics": "4.4.0-dev.4",
75
+ "@faststore/lighthouse": "4.4.0-dev.4",
76
+ "@faststore/api": "4.4.0-dev.4",
77
+ "@faststore/sdk": "4.4.0-dev.4",
78
+ "@faststore/ui": "4.4.0-dev.4"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@cypress/code-coverage": "^3.12.1",
@@ -1,4 +1,4 @@
1
- import { Link } from '@faststore/ui'
1
+ import Link from 'src/components/ui/Link'
2
2
 
3
3
  import menuRoutes from 'src/customizations/src/myAccount/navigation'
4
4
  import { useAccountNavigationLabels } from 'src/sdk/account/accountPageContext'
@@ -1,6 +1,7 @@
1
- import { Button, Link } from '@faststore/ui'
1
+ import { Button } from '@faststore/ui'
2
2
  import { useRouter } from 'next/router'
3
3
 
4
+ import Link from 'src/components/ui/Link'
4
5
  import styles from '../section.module.scss'
5
6
 
6
7
  import { useAccountNavigationLabels } from 'src/sdk/account/accountPageContext'
@@ -8,6 +8,7 @@ import {
8
8
  } from '@faststore/ui'
9
9
 
10
10
  import { type MutableRefObject, useRef, useState } from 'react'
11
+ import { useLink } from 'src/sdk/ui/useLink'
11
12
  import type {
12
13
  MyAccountFilter_FacetsFragment,
13
14
  useMyAccountFilter,
@@ -61,6 +62,7 @@ function FilterSlider({
61
62
  toLabel,
62
63
  invalidDateRangeLabel,
63
64
  }: FilterSliderProps & ReturnType<typeof useMyAccountFilter>) {
65
+ const { resolveLink } = useLink()
64
66
  const dateRangeInputRef = useRef<{
65
67
  clear: () => void
66
68
  getDataRangeFacet: () => {
@@ -121,7 +123,9 @@ function FilterSlider({
121
123
  }
122
124
  })
123
125
 
124
- window.location.href = `/pvt/account/orders?${params.toString()}`
126
+ const ordersHref =
127
+ resolveLink('/pvt/account/orders') ?? '/pvt/account/orders'
128
+ window.location.href = `${ordersHref}?${params.toString()}`
125
129
  }
126
130
 
127
131
  return (
@@ -20,6 +20,7 @@ import {
20
20
  type MyAccountFilter_FacetsFragment,
21
21
  type SelectedFacet,
22
22
  } from 'src/sdk/search/useMyAccountFilter'
23
+ import { useLink } from 'src/sdk/ui/useLink'
23
24
  import useScreenResize from 'src/sdk/ui/useScreenResize'
24
25
  import { FastStoreOrderStatus } from 'src/utils/userOrderStatus'
25
26
  import AccountHeader from '../../components/Header'
@@ -32,6 +33,8 @@ import ListOrdersTable, { Pagination } from './ListOrdersTable/ListOrdersTable'
32
33
  import SelectedFiltersTags from './SelectedTags/SelectedTags'
33
34
  import styles from './styles.module.scss'
34
35
 
36
+ const ORDERS_PATH = '/pvt/account/orders'
37
+
35
38
  export type ListOrdersProps = {
36
39
  listOrders: ServerListOrdersQueryQuery['listUserOrders']
37
40
  total: number
@@ -145,6 +148,8 @@ export default function ListOrders({
145
148
  }: ListOrdersProps) {
146
149
  const labels = resolveListOrdersLabels(labelsProp)
147
150
  const router = useRouter()
151
+ const { resolveLink } = useLink()
152
+ const ordersHref = resolveLink(ORDERS_PATH) ?? ORDERS_PATH
148
153
  const { isDesktop } = useScreenResize()
149
154
  const searchInputRef = useRef(null) as MutableRefObject<SearchInputFieldRef>
150
155
 
@@ -179,7 +184,7 @@ export default function ListOrders({
179
184
  params.set('text', value)
180
185
  }
181
186
 
182
- window.location.href = `/pvt/account/orders?${params.toString()}`
187
+ window.location.href = `${ordersHref}?${params.toString()}`
183
188
  }
184
189
  },
185
190
  300,
@@ -263,7 +268,7 @@ export default function ListOrders({
263
268
  pendingMyApproval: filters.pendingMyApproval,
264
269
  }}
265
270
  onClearAll={() => {
266
- window.location.href = '/pvt/account/orders'
271
+ window.location.href = ordersHref
267
272
  }}
268
273
  onRemoveFilter={(key, value) => {
269
274
  const { page, clientEmail, ...updatedFilters } = { ...filters }
@@ -289,7 +294,7 @@ export default function ListOrders({
289
294
  const params = new URLSearchParams(
290
295
  filteredQuery as Record<string, string>
291
296
  )
292
- window.location.href = `/pvt/account/orders?${params.toString()}`
297
+ window.location.href = `${ordersHref}?${params.toString()}`
293
298
  }}
294
299
  />
295
300
 
@@ -1,10 +1,11 @@
1
1
  import { Icon, IconButton } from '@faststore/ui'
2
2
 
3
+ import { useRouter } from 'next/router'
3
4
  import { useState } from 'react'
4
5
 
5
6
  import StatusBadge from 'src/components/account/components/StatusBadge'
6
7
  import { useFormatPrice } from 'src/components/account/utils/useFormatPrice'
7
- import { useSession } from 'src/sdk/session'
8
+ import { useLink } from 'src/sdk/ui/useLink'
8
9
  import useScreenResize from 'src/sdk/ui/useScreenResize'
9
10
  import { ExpandButton } from './ExpandButton/ExpandButton'
10
11
 
@@ -53,6 +54,8 @@ export function Pagination({
53
54
  labels?: ListOrdersSectionLabels
54
55
  }) {
55
56
  const labels = resolveListOrdersLabels(labelsProp)
57
+ const { resolveLink } = useLink()
58
+ const ordersHref = resolveLink('/pvt/account/orders') ?? '/pvt/account/orders'
56
59
  const totalPages = Math.ceil(total / perPage)
57
60
  const firstIndexLabel = page === 1 ? 1 : (page - 1) * perPage + 1
58
61
  const lastIndexLabel =
@@ -67,7 +70,7 @@ export function Pagination({
67
70
  } else {
68
71
  params.set('page', String(newPage))
69
72
  }
70
- window.location.href = `/pvt/account/orders${params.toString() ? `?${params}` : ''}`
73
+ window.location.href = `${ordersHref}${params.toString() ? `?${params}` : ''}`
71
74
  }
72
75
 
73
76
  return (
@@ -105,7 +108,7 @@ export default function ListOrdersTable({
105
108
  const labels = resolveListOrdersLabels(labelsProp)
106
109
  const statusLabels = pickOrderStatusCmsLabels(labels)
107
110
  const { isDesktop } = useScreenResize()
108
- const { locale } = useSession()
111
+ const { locale } = useRouter()
109
112
  const formatPrice = useFormatPrice()
110
113
 
111
114
  const [expandedRows, setExpandedRows] = useState<
@@ -1,5 +1,5 @@
1
1
  import { Button } from '@faststore/ui'
2
- import { useSession } from 'src/sdk/session'
2
+ import { useRouter } from 'next/router'
3
3
  import {
4
4
  type ListOrdersSectionLabels,
5
5
  getStatusDisplayLabels,
@@ -48,7 +48,7 @@ function Tags({
48
48
  }: Pick<SelectedTagsProps, 'filters' | 'onRemoveFilter' | 'labels'>) {
49
49
  const labels = resolveListOrdersLabels(labelsProp)
50
50
  const statusDisplayLabels = getStatusDisplayLabels(labels)
51
- const { locale } = useSession()
51
+ const { locale } = useRouter()
52
52
  const { dateInitial, dateFinal, status, pendingMyApproval } = filters
53
53
 
54
54
  const formattedDateInitial = dateInitial
@@ -1,6 +1,7 @@
1
1
  import { Icon as UIIcon, IconButton as UIIconButton } from '@faststore/ui'
2
2
  import type { PropsWithChildren } from 'react'
3
3
  import type { ServerOrderDetailsQueryQuery } from '@generated/graphql'
4
+ import { useLink } from 'src/sdk/ui/useLink'
4
5
  import type { OrderStatusCmsLabels } from 'src/utils/userOrderStatus'
5
6
  import StatusBadge from '../../components/StatusBadge'
6
7
  import BuyingPolicyAlert from './BuyingPolicyAlert'
@@ -12,6 +13,8 @@ import {
12
13
  } from './orderDetailsLabels'
13
14
  import styles from './section.module.scss'
14
15
 
16
+ const ORDERS_PATH = '/pvt/account/orders'
17
+
15
18
  export type OrderDetailsHeaderProps = {
16
19
  order: ServerOrderDetailsQueryQuery['userOrder']
17
20
  labels?: OrderDetailsHeaderLabels
@@ -24,12 +27,14 @@ export function OrderDetailsHeader({
24
27
  statusLabels,
25
28
  }: OrderDetailsHeaderProps) {
26
29
  const labels = resolveOrderDetailsHeaderLabels(labelsProp)
30
+ const { resolveLink } = useLink()
31
+ const ordersHref = resolveLink(ORDERS_PATH) ?? ORDERS_PATH
27
32
 
28
33
  return (
29
34
  <>
30
35
  <header data-fs-order-details-header>
31
36
  <div data-fs-order-details-header-title>
32
- <a href="/pvt/account/orders">
37
+ <a href={ordersHref}>
33
38
  <UIIconButton
34
39
  data-fs-order-details-header-back-button
35
40
  size="small"
@@ -1,9 +1,10 @@
1
- import { useSession } from 'src/sdk/session'
1
+ import { useRouter } from 'next/router'
2
2
  import { useCallback } from 'react'
3
3
 
4
4
  // Format price values according to the specified currency (converts cents to standard units)
5
5
  export const useFormatPrice = () => {
6
- const { locale } = useSession()
6
+ // get locale from router instead of using useSession to avoid SSR hydration issues
7
+ const { locale } = useRouter()
7
8
 
8
9
  return useCallback(
9
10
  (value: number, currencyCode: string) => {
@@ -45,6 +45,12 @@ const Link = forwardRef<HTMLAnchorElement, LinkProps>(function Link<
45
45
  inverse={inverse}
46
46
  passHref
47
47
  href={finalHref}
48
+ // resolveLink already produces the fully localized href (custom path or
49
+ // explicit locale prefix), so NextLink must not add its own locale
50
+ // prefix on top of it. Otherwise SSR over-localizes (e.g.
51
+ // /it-IT/europe/it/...) while the client keeps /europe/it/..., causing
52
+ // a hydration mismatch.
53
+ locale={false}
48
54
  legacyBehavior={false}
49
55
  prefetch={prefetch}
50
56
  {...otherProps}
@@ -79,3 +79,6 @@ export type {
79
79
  Locale,
80
80
  } from '../sdk/localization/types'
81
81
  export type { UseBindingSelectorReturn } from '../sdk/localization/useBindingSelector'
82
+ export { useLink as useLink_unstable } from '../sdk/ui/useLink'
83
+ export { default as Link_unstable } from '../components/ui/Link'
84
+ export { localizeRedirectDestination as localizeRedirectDestination_unstable } from '../utils/localization/localizeRedirectDestination'
@@ -15,6 +15,7 @@ import { execute } from 'src/server'
15
15
 
16
16
  import { validateUser } from 'src/sdk/account/validateUser'
17
17
  import { injectGlobalSections } from 'src/server/cms/global'
18
+ import { localizeRedirectDestination } from 'src/utils/localization/localizeRedirectDestination'
18
19
  import { withLocaleValidationSSR } from 'src/utils/localization/withLocaleValidation'
19
20
  import { getMyAccountRedirect } from 'src/utils/myAccountRedirect'
20
21
  import storeConfig from '../../discovery.config'
@@ -48,7 +49,7 @@ const getServerSidePropsBase: GetServerSideProps<
48
49
  if (!validationResult.isValid && !validationResult.needsRefresh) {
49
50
  return {
50
51
  redirect: {
51
- destination: '/login',
52
+ destination: localizeRedirectDestination('/login', context),
52
53
  permanent: false,
53
54
  },
54
55
  }
@@ -59,7 +60,10 @@ const getServerSidePropsBase: GetServerSideProps<
59
60
  const currentPath = context.req.url || '/pvt/account'
60
61
  return {
61
62
  redirect: {
62
- destination: `/pvt/account/403?from=${encodeURIComponent(currentPath)}`,
63
+ destination: localizeRedirectDestination(
64
+ `/pvt/account/403?from=${encodeURIComponent(currentPath)}`,
65
+ context
66
+ ),
63
67
  permanent: false,
64
68
  },
65
69
  }
@@ -24,6 +24,7 @@ import PageProvider from 'src/sdk/overrides/PageProvider'
24
24
  import { execute } from 'src/server'
25
25
  import { type PageContentType, getPage } from 'src/server/cms'
26
26
  import { injectGlobalSections } from 'src/server/cms/global'
27
+ import { localizeRedirectDestination } from 'src/utils/localization/localizeRedirectDestination'
27
28
  import { withLocaleValidationSSR } from 'src/utils/localization/withLocaleValidation'
28
29
  import { getMyAccountRedirect } from 'src/utils/myAccountRedirect'
29
30
 
@@ -128,7 +129,10 @@ const getServerSidePropsBase: GetServerSideProps<
128
129
  if (statusCode === 401 || statusCode === 403) {
129
130
  return {
130
131
  redirect: {
131
- destination: `/pvt/account/403?from=${encodeURIComponent('/pvt/account/404')}`,
132
+ destination: localizeRedirectDestination(
133
+ `/pvt/account/403?from=${encodeURIComponent('/pvt/account/404')}`,
134
+ context
135
+ ),
132
136
  permanent: false,
133
137
  },
134
138
  }
@@ -2,6 +2,7 @@ import type { Locator } from '@vtex/client-cms'
2
2
  import type { GetStaticPaths, GetStaticProps } from 'next'
3
3
 
4
4
  import type { MyAccountProps } from 'src/experimental/myAccountServerSideProps'
5
+ import { localizeRedirectDestination } from 'src/utils/localization/localizeRedirectDestination'
5
6
  import { getMyAccountRedirect } from 'src/utils/myAccountRedirect'
6
7
 
7
8
  export default function Page() {
@@ -12,7 +13,7 @@ export const getStaticProps: GetStaticProps<
12
13
  MyAccountProps,
13
14
  Record<string, string>,
14
15
  Locator
15
- > = async () => {
16
+ > = async ({ locale, defaultLocale }) => {
16
17
  const { isFaststoreMyAccountEnabled, redirect } = getMyAccountRedirect({
17
18
  query: {},
18
19
  })
@@ -23,7 +24,10 @@ export const getStaticProps: GetStaticProps<
23
24
 
24
25
  return {
25
26
  redirect: {
26
- destination: '/pvt/account/404',
27
+ destination: localizeRedirectDestination('/pvt/account/404', {
28
+ locale,
29
+ defaultLocale,
30
+ }),
27
31
  permanent: false,
28
32
  },
29
33
  }
@@ -1,14 +1,15 @@
1
1
  import type { GetServerSideProps, NextPage } from 'next'
2
- import { getMyAccountRedirect } from 'src/utils/myAccountRedirect'
2
+ import { localizeRedirectDestination } from 'src/utils/localization/localizeRedirectDestination'
3
3
  import { withLocaleValidationSSR } from 'src/utils/localization/withLocaleValidation'
4
+ import { getMyAccountRedirect } from 'src/utils/myAccountRedirect'
4
5
 
5
6
  const MyAccountRedirectPage: NextPage = () => {
6
7
  return null
7
8
  }
8
9
 
9
- const getServerSidePropsBase: GetServerSideProps = async ({ query, req }) => {
10
+ const getServerSidePropsBase: GetServerSideProps = async (context) => {
10
11
  const { isFaststoreMyAccountEnabled, redirect } = getMyAccountRedirect({
11
- query,
12
+ query: context.query,
12
13
  })
13
14
 
14
15
  if (!isFaststoreMyAccountEnabled) {
@@ -17,7 +18,7 @@ const getServerSidePropsBase: GetServerSideProps = async ({ query, req }) => {
17
18
 
18
19
  return {
19
20
  redirect: {
20
- destination: '/pvt/account/profile',
21
+ destination: localizeRedirectDestination('/pvt/account/profile', context),
21
22
  permanent: false,
22
23
  },
23
24
  }
@@ -27,6 +27,7 @@ import { injectGlobalSections } from 'src/server/cms/global'
27
27
  import { extractAccountNavigationData } from 'src/server/cms/myAccountDefaultSections'
28
28
  import { fetchMyAccountPageContent } from 'src/server/cms/fetchMyAccountPageContent'
29
29
  import { getMyAccountRedirect } from 'src/utils/myAccountRedirect'
30
+ import { localizeRedirectDestination } from 'src/utils/localization/localizeRedirectDestination'
30
31
  import { withLocaleValidationSSR } from 'src/utils/localization/withLocaleValidation'
31
32
 
32
33
  import storeConfig from 'discovery.config'
@@ -157,7 +158,7 @@ const getServerSidePropsBase: GetServerSideProps<
157
158
 
158
159
  return {
159
160
  redirect: {
160
- destination,
161
+ destination: localizeRedirectDestination(destination, context),
161
162
  permanent: false,
162
163
  },
163
164
  }
@@ -27,8 +27,9 @@ import { getIsRepresentative } from 'src/sdk/account/getIsRepresentative'
27
27
  import PageProvider from 'src/sdk/overrides/PageProvider'
28
28
  import { execute } from 'src/server'
29
29
  import { injectGlobalSections } from 'src/server/cms/global'
30
- import { extractAccountNavigationData } from 'src/server/cms/myAccountDefaultSections'
31
30
  import { fetchMyAccountPageContent } from 'src/server/cms/fetchMyAccountPageContent'
31
+ import { extractAccountNavigationData } from 'src/server/cms/myAccountDefaultSections'
32
+ import { localizeRedirectDestination } from 'src/utils/localization/localizeRedirectDestination'
32
33
  import { getMyAccountRedirect } from 'src/utils/myAccountRedirect'
33
34
  import { withLocaleValidationSSR } from 'src/utils/localization/withLocaleValidation'
34
35
 
@@ -119,7 +120,7 @@ const getServerSidePropsBase: GetServerSideProps<
119
120
  if (!isRepresentative) {
120
121
  return {
121
122
  redirect: {
122
- destination: '/pvt/account',
123
+ destination: localizeRedirectDestination('/pvt/account', context),
123
124
  permanent: false,
124
125
  },
125
126
  }
@@ -175,7 +176,7 @@ const getServerSidePropsBase: GetServerSideProps<
175
176
 
176
177
  return {
177
178
  redirect: {
178
- destination,
179
+ destination: localizeRedirectDestination(destination, context),
179
180
  permanent: false,
180
181
  },
181
182
  }