@faststore/core 4.4.0-dev.3 → 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 (30) hide show
  1. package/.turbo/turbo-generate.log +3 -3
  2. package/.turbo/turbo-test.log +48 -44
  3. package/CHANGELOG.md +6 -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/session/index.ts +9 -6
  23. package/src/sdk/session/initialSession.ts +31 -46
  24. package/src/utils/localization/localizeRedirectDestination.ts +66 -0
  25. package/src/utils/localization/withLocaleValidation.ts +0 -6
  26. package/test/proxy.localization.test.ts +122 -0
  27. package/test/sdk/session/reconcileSessionLocale.browser.test.ts +199 -0
  28. package/test/sdk/session/reconcileSessionLocale.disabled.browser.test.ts +38 -0
  29. package/test/utils/localization/localizeRedirectDestination.test.ts +176 -0
  30. package/test/sdk/session/installLocaleCorrector.browser.test.ts +0 -208
@@ -1,9 +1,9 @@
1
1
 
2
- > @faststore/core@4.4.0-dev.2 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.2 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.2 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,18 +1,18 @@
1
1
 
2
- > @faststore/core@4.4.0-dev.2 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) 74ms
10
- ✓  browser  test/utils/isLocalHost.browser.test.ts (3 tests) 14ms
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
11
11
  stderr | test/sdk/localization/store-url.browser.test.ts
12
12
  Error in optimistic validation: TypeError: Cannot read properties of undefined (reading 'read')
13
13
  at validateCart (/home/runner/work/faststore/faststore/packages/core/src/sdk/cart/index.ts:119:27)
14
14
  at onValidate (/home/runner/work/faststore/faststore/packages/core/src/sdk/useStore.ts:18:20)
15
- 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)
16
16
   at processTicksAndRejections (node:internal/process/task_queues:103:5)
17
17
 
18
18
  stderr | test/pages/password-protection.browser.test.tsx > PasswordProtectionLogin > posts the password and redirects to the requested return path
@@ -100,7 +100,6 @@ act(() => {
100
100
  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
101
101
  at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
102
102
 
103
- ✓  node  test/utils/localization/bindingPaths.test.ts (71 tests) 38ms
104
103
  stderr | test/pages/password-protection.browser.test.tsx > PasswordProtectionLogin > uses the fallback invalid-password message when API omits an error
105
104
  Warning: An update to PasswordProtectionLogin inside a test was not wrapped in act(...).
106
105
 
@@ -245,14 +244,16 @@ act(() => {
245
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
246
245
  at PasswordProtectionLogin (/home/runner/work/faststore/faststore/packages/core/src/pages/password-protection/index.tsx:19:69)
247
246
 
248
- ✓  browser  test/pages/password-protection.browser.test.tsx (6 tests) 1502ms
249
- ✓ renders the password protection form  667ms
250
- ✓  browser  test/sdk/localization/store-url.browser.test.ts (3 tests) 22ms
251
- ✓  node  test/utils/match-url.test.ts (10 tests) 34ms
252
- ✓  node  test/server/password-protection-service.test.ts (22 tests) 145ms
253
- ✓  node  test/sdk/localization/bindingSelector.test.ts (18 tests) 34ms
254
- ✓  node  test/pages/api/unlock.test.ts (15 tests) 790ms
255
- ✓ returns 405 for non-POST requests  528ms
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
 
@@ -316,17 +317,18 @@ Warning: React does not recognize the `providerProps` prop on a DOM element. If
316
317
  at Suspense
317
318
  at Wrapper (/home/runner/work/faststore/faststore/packages/core/test/components/search/SearchInputComponent.test.tsx:106:20)
318
319
 
319
- ✓  node  test/components/search/SearchInputComponent.test.tsx (6 tests) 198ms
320
- ✓  node  test/utils/cookieCacheBusting.test.ts (10 tests) 40ms
321
- ✓  node  test/sdk/localization/useBindingSelector.test.tsx (12 tests) 37ms
322
- ✓  node  test/sdk/search/useSearchHistory.test.ts (13 tests) 218ms
323
- ✓  node  test/utils/clearCookies.test.ts (20 tests) 99ms
324
- ✓  node  test/utils/multipleTemplates.test.ts (8 tests) 17ms
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
325
326
  stderr | test/sdk/account/useSetPassword.test.ts > useSetPassword > maps wrongcredentials error responses to the existing message
326
327
  Set password request failed: Bad Request
327
328
 
328
- ✓  node  test/sdk/account/useSetPassword.test.ts (6 tests) 48ms
329
- ✓  node  test/sdk/orderEntry/useOrderEntryOperation.test.ts (8 tests) 73ms
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,29 +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) 59ms
378
- ✓  node  test/sdk/orderEntry/useOrderEntry.test.ts (8 tests) 37ms
379
- ✓  node  test/proxy.test.ts (4 tests) 50ms
380
- ✓  node  test/sdk/orderEntry/useOrderFormItems.test.ts (7 tests) 52ms
381
- ✓  node  test/server/webops-api.test.ts (9 tests) 18ms
382
- ✓  node  test/server/index.test.ts (7 tests) 667ms
383
- ✓  node  test/server/cms/global.test.ts (3 tests) 7ms
384
- ✓  node  test/sdk/localization/store-url.test.ts (1 test) 4ms
385
- ✓  node  test/server/content/service.test.ts (5 tests) 4ms
386
- ✓  node  test/utils/getRequestHostname.test.ts (12 tests) 7ms
387
- ✓  node  test/sdk/auth/useAuth.test.ts (5 tests) 32ms
388
- ✓  node  test/pages/api/preview.test.ts (2 tests) 6ms
389
- ✓  node  test/utils/validateSessionRefreshToken.test.ts (6 tests) 4ms
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
388
+ ✓  node  test/server/content/service.test.ts (5 tests) 5ms
389
+ ✓  node  test/sdk/localization/store-url.test.ts (1 test) 5ms
390
+ ✓  node  test/utils/getRequestHostname.test.ts (12 tests) 6ms
391
+ ✓  node  test/sdk/auth/useAuth.test.ts (5 tests) 33ms
392
+ ✓  node  test/pages/api/preview.test.ts (2 tests) 10ms
393
+ ✓  node  test/utils/validateSessionRefreshToken.test.ts (6 tests) 6ms
394
+ ✓  node  test/components/search/SearchInput.test.ts (6 tests) 11ms
390
395
  ✓  node  test/utils/unlockResponse.test.ts (11 tests) 5ms
391
- ✓  node  test/components/search/SearchInput.test.ts (6 tests) 7ms
392
- ✓  node  test/server/cms/index.test.ts (2 tests) 6ms
393
- ✓  node  test/utils/isLocalHost.test.ts (7 tests) 7ms
396
+ ✓  node  test/server/cms/index.test.ts (2 tests) 8ms
397
+ ✓  node  test/utils/isLocalHost.test.ts (7 tests) 5ms
394
398
  ✓  node  test/utils/userOrderStatus.test.ts (3 tests) 3ms
395
- ✓  node  test/components/auth/ProfileChallenge.test.tsx (3 tests) 25ms
399
+ ✓  node  test/components/auth/ProfileChallenge.test.tsx (3 tests) 26ms
396
400
 
397
-  Test Files  38 passed (38)
398
-  Tests  363 passed (363)
399
-  Start at  13:16:14
400
-  Duration  23.17s (transform 6.25s, setup 0ms, collect 17.58s, tests 4.44s, environment 28.99s, prepare 945ms)
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)
401
405
 
package/CHANGELOG.md CHANGED
@@ -3,6 +3,12 @@
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
+
6
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)
7
13
 
8
14
  ### Bug Fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/core",
3
- "version": "4.4.0-dev.3",
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/api": "4.4.0-dev.3",
75
- "@faststore/diagnostics": "4.4.0-dev.3",
76
- "@faststore/sdk": "4.4.0-dev.3",
77
- "@faststore/lighthouse": "4.4.0-dev.3",
78
- "@faststore/ui": "4.4.0-dev.3"
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
  }