@faststore/core 3.42.0 → 3.44.0

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 (210) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +55 -55
  3. package/.next/cache/.tsbuildinfo +1 -1
  4. package/.next/cache/config.json +3 -3
  5. package/.next/cache/webpack/client-production/0.pack +0 -0
  6. package/.next/cache/webpack/client-production/index.pack +0 -0
  7. package/.next/cache/webpack/server-production/0.pack +0 -0
  8. package/.next/cache/webpack/server-production/index.pack +0 -0
  9. package/.next/prerender-manifest.js +1 -1
  10. package/.next/prerender-manifest.json +1 -1
  11. package/.next/react-loadable-manifest.json +65 -65
  12. package/.next/routes-manifest.json +1 -1
  13. package/.next/server/chunks/1506.js +1 -1
  14. package/.next/server/chunks/2443.js +1 -0
  15. package/.next/server/chunks/2524.js +1 -0
  16. package/.next/server/chunks/4289.js +2 -362
  17. package/.next/server/chunks/4559.js +361 -0
  18. package/.next/server/chunks/4725.js +1 -0
  19. package/.next/server/chunks/4746.js +1 -1
  20. package/.next/server/chunks/5474.js +6 -0
  21. package/.next/server/chunks/5607.js +1 -0
  22. package/.next/server/chunks/563.js +1 -1
  23. package/.next/server/chunks/6594.js +1 -1
  24. package/.next/server/chunks/674.js +1 -1
  25. package/.next/server/chunks/6968.js +10 -0
  26. package/.next/server/chunks/7986.js +6 -1
  27. package/.next/server/chunks/804.js +1 -0
  28. package/.next/server/chunks/831.js +1 -1
  29. package/.next/server/chunks/8562.js +1 -1
  30. package/.next/server/chunks/8646.js +1 -1
  31. package/.next/server/chunks/ButtonSignIn.js +1 -1
  32. package/.next/server/chunks/UIBannerText.js +1 -1
  33. package/.next/server/chunks/UISKUMatrixSidebar.js +1 -1
  34. package/.next/server/middleware-build-manifest.js +1 -1
  35. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  36. package/.next/server/pages/404.js +1 -1
  37. package/.next/server/pages/404.js.nft.json +1 -1
  38. package/.next/server/pages/500.js +1 -1
  39. package/.next/server/pages/500.js.nft.json +1 -1
  40. package/.next/server/pages/[...slug].js +1 -1
  41. package/.next/server/pages/[...slug].js.nft.json +1 -1
  42. package/.next/server/pages/[slug]/p.js +1 -1
  43. package/.next/server/pages/[slug]/p.js.nft.json +1 -1
  44. package/.next/server/pages/_app.js +1 -1
  45. package/.next/server/pages/_app.js.nft.json +1 -1
  46. package/.next/server/pages/_document.js +1 -1
  47. package/.next/server/pages/_document.js.nft.json +1 -1
  48. package/.next/server/pages/_error.js +1 -1
  49. package/.next/server/pages/_error.js.nft.json +1 -1
  50. package/.next/server/pages/account/profile.js +1 -1
  51. package/.next/server/pages/account/profile.js.nft.json +1 -1
  52. package/.next/server/pages/account.js +1 -1
  53. package/.next/server/pages/account.js.nft.json +1 -1
  54. package/.next/server/pages/api/graphql.js +2 -1
  55. package/.next/server/pages/api/graphql.js.nft.json +1 -1
  56. package/.next/server/pages/api/health/live.js.nft.json +1 -1
  57. package/.next/server/pages/api/health/ready.js.nft.json +1 -1
  58. package/.next/server/pages/api/preview.js +1 -1
  59. package/.next/server/pages/api/preview.js.nft.json +1 -1
  60. package/.next/server/pages/checkout.js +1 -1
  61. package/.next/server/pages/checkout.js.nft.json +1 -1
  62. package/.next/server/pages/en-US/404.html +2 -2
  63. package/.next/server/pages/en-US/500.html +2 -2
  64. package/.next/server/pages/en-US/checkout.html +2 -2
  65. package/.next/server/pages/en-US/login.html +2 -2
  66. package/.next/server/pages/en-US/s.html +2 -2
  67. package/.next/server/pages/en-US.html +2 -2
  68. package/.next/server/pages/index.js +1 -1
  69. package/.next/server/pages/index.js.nft.json +1 -1
  70. package/.next/server/pages/login.js +1 -1
  71. package/.next/server/pages/login.js.nft.json +1 -1
  72. package/.next/server/pages/s.js +1 -1
  73. package/.next/server/pages/s.js.nft.json +1 -1
  74. package/.next/server/pages-manifest.json +1 -1
  75. package/.next/static/U_9W0qMyv_4RQSLFdrtHC/_buildManifest.js +1 -0
  76. package/.next/static/chunks/{1153.ed17e19083f51bdb.js → 1153.8f0ac867c4ddce90.js} +1 -1
  77. package/.next/static/chunks/1173.ca14a5bc4e1264f4.js +1 -0
  78. package/.next/static/chunks/1418-e86227bcf9a5d486.js +28 -0
  79. package/.next/static/chunks/1552.8751332da83cadc5.js +1 -0
  80. package/.next/static/chunks/{6076.d80e37e35892bafc.js → 3684.3e6f435506c2c7c9.js} +1 -1
  81. package/.next/static/chunks/417.edbb75ab2f55482f.js +1 -0
  82. package/.next/static/chunks/{4349-6fc936580b772e67.js → 4349-87a956a73b97519c.js} +1 -1
  83. package/.next/static/chunks/{4625-9a273e78866c389b.js → 4625-553d20c86b0ca577.js} +1 -1
  84. package/.next/static/chunks/{4746.19eddeaeb33ea820.js → 4746.2e16ec0663a3873f.js} +1 -1
  85. package/.next/static/chunks/{4774.907a71a04126d57c.js → 4774.8e70c01dcd0ed4b3.js} +1 -1
  86. package/.next/static/chunks/{4865.3e2ae9feb511c870.js → 4865.4017be0f8e7c8cf0.js} +1 -1
  87. package/.next/static/chunks/5836.c5c244a8cbfa7f7d.js +1 -0
  88. package/.next/static/chunks/630.13d3dd939b789798.js +6 -0
  89. package/.next/static/chunks/6335-6eb4ff84af184b88.js +1 -0
  90. package/.next/static/chunks/6536.d5260107222db13c.js +1 -0
  91. package/.next/static/chunks/{7195.e88924bd232c58b7.js → 7195.fd4cacc0bef1a233.js} +1 -1
  92. package/.next/static/chunks/7498-72289e704e7c7056.js +1 -0
  93. package/.next/static/chunks/7959.7c721505286572c0.js +1 -0
  94. package/.next/static/chunks/9.89f24163370f3a22.js +1 -0
  95. package/.next/static/chunks/BannerNewsletter.8982f42e60ed8828.js +1 -0
  96. package/.next/static/chunks/{ButtonSignIn.df0e3ce490436fe2.js → ButtonSignIn.bff8dc7b2133806c.js} +1 -1
  97. package/.next/static/chunks/CartItem.f2493be7c504f22f.js +1 -0
  98. package/.next/static/chunks/{CartSidebar.26d3e39bf93a368f.js → CartSidebar.aa9e43be37034654.js} +1 -1
  99. package/.next/static/chunks/{Gift.affb75f8f7bcb6db.js → Gift.375356d6a74e2693.js} +1 -1
  100. package/.next/static/chunks/Newsletter.9db4df2d4fb33227.js +1 -0
  101. package/.next/static/chunks/OrderSummary.e6e0a3af3c224b4e.js +1 -0
  102. package/.next/static/chunks/ProductShelf.9cea36116836c161.js +1 -0
  103. package/.next/static/chunks/ProductTiles.059a4a6360e1d4ea.js +1 -0
  104. package/.next/static/chunks/RegionModal.4594b707a1092551.js +1 -0
  105. package/.next/static/chunks/UIBannerText.45cf608e46cde628.js +1 -0
  106. package/.next/static/chunks/UIButton.3186f933c0ecfb31.js +1 -0
  107. package/.next/static/chunks/UISKUMatrixSidebar.9ac3980a60cfc358.js +1 -0
  108. package/.next/static/chunks/UIToast.221eb10681d2f642.js +1 -0
  109. package/.next/static/chunks/pages/{404-8e61ea158e7b314c.js → 404-6300c433469b7262.js} +1 -1
  110. package/.next/static/chunks/pages/{500-68f51177e64de6e7.js → 500-2d1dd344c8a8827f.js} +1 -1
  111. package/.next/static/chunks/pages/[...slug]-c1a62d58f5940747.js +1 -0
  112. package/.next/static/chunks/pages/[slug]/p-555dc09a5e78260e.js +1 -0
  113. package/.next/static/chunks/pages/_app-929466ed763a6d46.js +1 -0
  114. package/.next/static/chunks/pages/account/{profile-1fdb500de8f12b3a.js → profile-23b2e9fbbd95a30b.js} +1 -1
  115. package/.next/static/chunks/pages/{checkout-0dfe0dc9cee443ba.js → checkout-93b647fc45454d97.js} +1 -1
  116. package/.next/static/chunks/pages/{index-d36123e232b889d8.js → index-07bc320fc045538c.js} +1 -1
  117. package/.next/static/chunks/pages/{login-b59ea5561defc0d4.js → login-2454f1cd309c27d2.js} +1 -1
  118. package/.next/static/chunks/pages/{s-6120de2f57d674fc.js → s-9901e6857f517b8b.js} +1 -1
  119. package/.next/static/chunks/webpack-c2eed1e0b727b3ee.js +1 -0
  120. package/.next/static/css/b8945ac5f5327c34.css +1 -0
  121. package/.next/static/css/{f03f8973f7c72071.css → dbbb10bf2f162a58.css} +1 -1
  122. package/.next/trace +113 -109
  123. package/.turbo/turbo-build.log +25 -25
  124. package/.turbo/turbo-test.log +5 -5
  125. package/@generated/gql.ts +18 -2
  126. package/@generated/graphql.ts +58 -1
  127. package/@generated/persisted-documents.json +3 -1
  128. package/@generated/schema.graphql +14 -0
  129. package/CHANGELOG.md +12 -0
  130. package/cms/faststore/sections.json +110 -1
  131. package/discovery.config.default.js +12 -0
  132. package/package.json +7 -6
  133. package/src/Layout.tsx +2 -0
  134. package/src/components/cms/GlobalSections.tsx +13 -9
  135. package/src/components/cms/global/Components.ts +2 -0
  136. package/src/components/region/RegionBar/RegionBar.tsx +35 -2
  137. package/src/components/region/RegionButton/RegionButton.tsx +41 -6
  138. package/src/components/region/RegionModal/RegionModal.tsx +46 -34
  139. package/src/components/region/RegionModal/useRegion.ts +79 -0
  140. package/src/components/region/RegionModal/useRegionModal.ts +44 -0
  141. package/src/components/region/RegionPopover/RegionPopover.tsx +174 -0
  142. package/src/components/region/RegionPopover/index.ts +1 -0
  143. package/src/components/region/RegionPopover/section.module.scss +9 -0
  144. package/src/components/search/SearchInput/SearchInput.tsx +2 -2
  145. package/src/components/sections/Navbar/section.module.scss +3 -0
  146. package/src/components/sections/RegionBar/RegionBar.tsx +8 -3
  147. package/src/components/templates/LandingPage/LandingPage.tsx +22 -18
  148. package/src/components/templates/ProductListingPage/ProductListing.tsx +6 -1
  149. package/src/constants.ts +1 -0
  150. package/src/experimental/searchServerSideFunctions/getServerSideProps.ts +8 -5
  151. package/src/experimental/searchServerSideFunctions/getStaticProps.ts +9 -7
  152. package/src/pages/404.tsx +6 -5
  153. package/src/pages/500.tsx +6 -5
  154. package/src/pages/[...slug].tsx +11 -4
  155. package/src/pages/[slug]/p.tsx +16 -6
  156. package/src/pages/_app.tsx +4 -2
  157. package/src/pages/api/preview.ts +43 -18
  158. package/src/pages/index.tsx +9 -7
  159. package/src/pages/login.tsx +6 -5
  160. package/src/sdk/error/MissingContentError/MissingContentError.ts +6 -4
  161. package/src/sdk/error/MultipleContentError/MultipleContentError.ts +6 -4
  162. package/src/sdk/geolocation/useGeolocation.ts +42 -0
  163. package/src/sdk/product/index.ts +21 -0
  164. package/src/sdk/profile/index.ts +31 -0
  165. package/src/sdk/session/index.ts +37 -0
  166. package/src/sdk/ui/useOnClickOutside.ts +3 -38
  167. package/src/server/cms/index.ts +1 -2
  168. package/src/server/content/service.ts +227 -0
  169. package/src/server/content/types.ts +26 -0
  170. package/src/server/content/utils.ts +8 -0
  171. package/src/utils/utilities.ts +9 -1
  172. package/test/server/index.test.ts +1 -0
  173. package/.next/server/chunks/3105.js +0 -6
  174. package/.next/server/chunks/3779.js +0 -1
  175. package/.next/server/chunks/4444.js +0 -6
  176. package/.next/server/chunks/6026.js +0 -9
  177. package/.next/server/chunks/6030.js +0 -1
  178. package/.next/server/chunks/7337.js +0 -1
  179. package/.next/server/chunks/7675.js +0 -1
  180. package/.next/server/chunks/9594.js +0 -1
  181. package/.next/static/Ra_8xXVEVCNHcT2KePSUO/_buildManifest.js +0 -1
  182. package/.next/static/chunks/1036.27f5244aaf7d0915.js +0 -1
  183. package/.next/static/chunks/1173.5e86a9295010b785.js +0 -1
  184. package/.next/static/chunks/1552.e7cece605fc2e1cd.js +0 -1
  185. package/.next/static/chunks/3684.ba7a2a994988063b.js +0 -1
  186. package/.next/static/chunks/417.c39c1c5e5ef57b4a.js +0 -1
  187. package/.next/static/chunks/485.a35fab0c7c75a11b.js +0 -1
  188. package/.next/static/chunks/6167-ecb49640dcb9d566.js +0 -28
  189. package/.next/static/chunks/6335-5870fc075bf96b86.js +0 -1
  190. package/.next/static/chunks/6536.cd75ac69c241a35c.js +0 -1
  191. package/.next/static/chunks/7498-415859c993f5002b.js +0 -1
  192. package/.next/static/chunks/7959.9d31abae51a7e419.js +0 -1
  193. package/.next/static/chunks/9.e42e9b7463b94493.js +0 -1
  194. package/.next/static/chunks/BannerNewsletter.06b2b9724aa3c3ea.js +0 -1
  195. package/.next/static/chunks/CartItem.44cc90c698a69889.js +0 -1
  196. package/.next/static/chunks/Newsletter.d775e641d99322e6.js +0 -1
  197. package/.next/static/chunks/OrderSummary.8f34504b20564fec.js +0 -1
  198. package/.next/static/chunks/ProductShelf.0b5a71a93bca3148.js +0 -1
  199. package/.next/static/chunks/ProductTiles.a75612c0bcf990d6.js +0 -1
  200. package/.next/static/chunks/RegionModal.68b05bfd591d27fc.js +0 -1
  201. package/.next/static/chunks/UIBannerText.5ee380812ac3772c.js +0 -1
  202. package/.next/static/chunks/UIButton.c7a3273ac6ee5da5.js +0 -1
  203. package/.next/static/chunks/UISKUMatrixSidebar.c68540bda6d40e13.js +0 -1
  204. package/.next/static/chunks/UIToast.85ae30e3e8cc5ec7.js +0 -1
  205. package/.next/static/chunks/pages/[...slug]-f4fd6c8d7dc53f8f.js +0 -1
  206. package/.next/static/chunks/pages/[slug]/p-3b513ae37c648620.js +0 -1
  207. package/.next/static/chunks/pages/_app-0f16b6b5d7dfab2a.js +0 -1
  208. package/.next/static/chunks/webpack-d72e5eb27bf80195.js +0 -1
  209. package/.next/static/css/31fb64e064998460.css +0 -1
  210. /package/.next/static/{Ra_8xXVEVCNHcT2KePSUO → U_9W0qMyv_4RQSLFdrtHC}/_ssgManifest.js +0 -0
@@ -1,3 +1,4 @@
1
+ import useScreenResize from 'src/sdk/ui/useScreenResize'
1
2
  import { getOverridableSection } from '../../..//sdk/overrides/getOverriddenSection'
2
3
  import RegionBar, {
3
4
  type RegionBarProps,
@@ -30,10 +31,14 @@ type RegionBarSectionProps = {
30
31
  }
31
32
 
32
33
  function RegionBarSection({ ...otherProps }: RegionBarSectionProps) {
34
+ const { isDesktop } = useScreenResize()
35
+
33
36
  return (
34
- <Section className={`${styles.section} section-region-bar display-mobile`}>
35
- <RegionBar {...otherProps} />
36
- </Section>
37
+ !isDesktop && (
38
+ <Section className={`${styles.section} section-region-bar`}>
39
+ <RegionBar {...otherProps} />
40
+ </Section>
41
+ )
37
42
  )
38
43
  }
39
44
 
@@ -1,4 +1,3 @@
1
- import type { Locator } from '@vtex/client-cms'
2
1
  import { NextSeo, SiteLinksSearchBoxJsonLd } from 'next-seo'
3
2
  import type { ComponentType } from 'react'
4
3
 
@@ -17,9 +16,10 @@ import { default as GLOBAL_COMPONENTS } from 'src/components/cms/global/Componen
17
16
  import MissingContentError from 'src/sdk/error/MissingContentError/MissingContentError'
18
17
  import PageProvider from 'src/sdk/overrides/PageProvider'
19
18
  import type { PageContentType } from 'src/server/cms'
20
- import { getPage } from 'src/server/cms'
21
19
 
22
20
  import storeConfig from 'discovery.config'
21
+ import type { PreviewData } from 'src/server/content/types'
22
+ import { contentService } from 'src/server/content/service'
23
23
 
24
24
  /* A list of components that can be used in the CMS. */
25
25
  const COMPONENTS: Record<string, ComponentType<any>> = {
@@ -105,7 +105,7 @@ export default function LandingPage({
105
105
 
106
106
  export const getLandingPageBySlug = async (
107
107
  slug: string,
108
- previewData: Locator
108
+ previewData: PreviewData
109
109
  ) => {
110
110
  try {
111
111
  if (storeConfig.cms.data) {
@@ -115,26 +115,30 @@ export const getLandingPageBySlug = async (
115
115
  })
116
116
 
117
117
  if (pageBySlug) {
118
- const landingPageData = await getPage<PageContentType>({
119
- contentType: 'landingPage',
120
- documentId: pageBySlug.documentId,
121
- versionId: pageBySlug.versionId,
122
- })
118
+ const landingPageData =
119
+ await contentService.getSingleContent<PageContentType>({
120
+ contentType: 'landingPage',
121
+ previewData,
122
+ documentId: pageBySlug.documentId,
123
+ versionId: pageBySlug.versionId,
124
+ releaseId: pageBySlug.releaseId,
125
+ slug: pageBySlug.settings?.seo?.slug,
126
+ })
123
127
 
124
128
  return landingPageData
125
129
  }
126
130
  }
127
131
 
128
- const landingPageData = await getPage<PageContentType>({
129
- ...(previewData?.contentType === 'landingPage'
130
- ? previewData
131
- : {
132
- filters: {
133
- filters: { 'settings.seo.slug': `/${slug}` },
134
- },
135
- }),
136
- contentType: 'landingPage',
137
- })
132
+ const landingPageData =
133
+ await contentService.getSingleContent<PageContentType>({
134
+ contentType: 'landingPage',
135
+ previewData,
136
+ slug,
137
+ filters:
138
+ previewData?.contentType !== 'landingPage'
139
+ ? { filters: { 'settings.seo.slug': `/${slug}` } }
140
+ : undefined,
141
+ })
138
142
  return landingPageData
139
143
  } catch (error) {
140
144
  if (error instanceof MissingContentError) {
@@ -23,6 +23,8 @@ import {
23
23
  } from 'src/sdk/product/usePageProductsQuery'
24
24
  import { useProductGalleryQuery } from 'src/sdk/product/useProductGalleryQuery'
25
25
  import { useApplySearchState } from 'src/sdk/search/state'
26
+ import { useRouter } from 'next/router'
27
+ import { isContentPlatformSource } from 'src/server/content/utils'
26
28
 
27
29
  const ScrollToTopButton = dynamic(
28
30
  () =>
@@ -49,6 +51,7 @@ export default function ProductListing({
49
51
  serverManyProductsVariables,
50
52
  globalSections,
51
53
  }: ProductListingPageProps) {
54
+ const router = useRouter()
52
55
  const { state } = useSearch()
53
56
  const { sort, term, selectedFacets } = state
54
57
 
@@ -56,7 +59,9 @@ export default function ProductListing({
56
59
 
57
60
  const applySearchState = useApplySearchState()
58
61
  useEffect(() => {
59
- applySearchState(formatSearchState(state))
62
+ if (!isContentPlatformSource() || !router.isPreview) {
63
+ applySearchState(formatSearchState(state))
64
+ }
60
65
  }, [])
61
66
 
62
67
  const { data: pageProductGalleryData } = useProductGalleryQuery({
package/src/constants.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export const ITEMS_PER_PAGE = 12
2
2
  export const ITEMS_PER_SECTION = 5
3
+ export const TIME_TO_VALIDATE_SESSION = 3000
@@ -1,16 +1,17 @@
1
1
  import type { GetServerSideProps } from 'next'
2
2
  import type { SearchPageProps } from './getStaticProps'
3
3
 
4
- import type { Locator } from '@vtex/client-cms'
5
4
  import storeConfig from 'discovery.config'
6
5
  import { getGlobalSectionsData } from 'src/components/cms/GlobalSections'
7
6
  import { type SearchContentType, getPage } from 'src/server/cms'
8
7
  import { injectGlobalSections } from 'src/server/cms/global'
8
+ import type { PreviewData } from 'src/server/content/types'
9
+ import { contentService } from 'src/server/content/service'
9
10
 
10
11
  export const getServerSideProps: GetServerSideProps<
11
12
  SearchPageProps,
12
13
  Record<string, string>,
13
- Locator
14
+ PreviewData
14
15
  > = async (context) => {
15
16
  const { previewData, query, res } = context
16
17
  const searchTerm = (query.q as string)?.split('+').join(' ')
@@ -31,10 +32,12 @@ export const getServerSideProps: GetServerSideProps<
31
32
  globalSectionsHeader,
32
33
  globalSectionsFooter,
33
34
  ] = await Promise.all([
34
- getPage<SearchContentType>({
35
+ contentService.getSingleContent<SearchContentType>({
35
36
  contentType: 'search',
37
+ previewData,
36
38
  documentId: page.documentId,
37
39
  versionId: page.versionId,
40
+ releaseId: page.releaseId,
38
41
  }),
39
42
  globalSectionsPromise,
40
43
  globalSectionsHeaderPromise,
@@ -58,9 +61,9 @@ export const getServerSideProps: GetServerSideProps<
58
61
 
59
62
  const [page, globalSections, globalSectionsHeader, globalSectionsFooter] =
60
63
  await Promise.all([
61
- getPage<SearchContentType>({
62
- ...(previewData?.contentType === 'search' ? previewData : null),
64
+ contentService.getSingleContent<SearchContentType>({
63
65
  contentType: 'search',
66
+ previewData,
64
67
  }),
65
68
  globalSectionsPromise,
66
69
  globalSectionsHeaderPromise,
@@ -1,12 +1,13 @@
1
- import type { Locator } from '@vtex/client-cms'
2
1
  import storeConfig from 'discovery.config'
3
2
  import type { GetStaticProps } from 'next'
4
3
  import {
5
4
  getGlobalSectionsData,
6
5
  type GlobalSectionsData,
7
6
  } from 'src/components/cms/GlobalSections'
8
- import { getPage, type SearchContentType } from 'src/server/cms'
7
+ import type { SearchContentType } from 'src/server/cms'
9
8
  import { injectGlobalSections } from 'src/server/cms/global'
9
+ import { contentService } from 'src/server/content/service'
10
+ import type { PreviewData } from 'src/server/content/types'
10
11
 
11
12
  export type SearchPageProps = {
12
13
  page: SearchContentType
@@ -21,10 +22,9 @@ export type SearchPageProps = {
21
22
  export const getStaticProps: GetStaticProps<
22
23
  SearchPageProps,
23
24
  Record<string, string>,
24
- Locator
25
+ PreviewData
25
26
  > = async (context) => {
26
27
  const { previewData } = context
27
-
28
28
  const [
29
29
  globalSectionsPromise,
30
30
  globalSectionsHeaderPromise,
@@ -42,10 +42,12 @@ export const getStaticProps: GetStaticProps<
42
42
  globalSectionsHeader,
43
43
  globalSectionsFooter,
44
44
  ] = await Promise.all([
45
- getPage<SearchContentType>({
45
+ contentService.getSingleContent<SearchContentType>({
46
46
  contentType: 'search',
47
+ previewData,
47
48
  documentId: page.documentId,
48
49
  versionId: page.versionId,
50
+ releaseId: page.releaseId,
49
51
  }),
50
52
  globalSectionsPromise,
51
53
  globalSectionsHeaderPromise,
@@ -66,9 +68,9 @@ export const getStaticProps: GetStaticProps<
66
68
 
67
69
  const [page, globalSections, globalSectionsHeader, globalSectionsFooter] =
68
70
  await Promise.all([
69
- getPage<SearchContentType>({
70
- ...(previewData?.contentType === 'search' ? previewData : null),
71
+ contentService.getSingleContent<SearchContentType>({
71
72
  contentType: 'search',
73
+ previewData,
72
74
  }),
73
75
  globalSectionsPromise,
74
76
  globalSectionsHeaderPromise,
package/src/pages/404.tsx CHANGED
@@ -1,4 +1,3 @@
1
- import type { Locator } from '@vtex/client-cms'
2
1
  import type { GetStaticProps } from 'next'
3
2
  import { NextSeo } from 'next-seo'
4
3
  import type { ComponentType } from 'react'
@@ -12,8 +11,10 @@ import RenderSections from 'src/components/cms/RenderSections'
12
11
  import { OverriddenDefaultEmptyState as EmptyState } from 'src/components/sections/EmptyState/OverriddenDefaultEmptyState'
13
12
  import CUSTOM_COMPONENTS from 'src/customizations/src/components'
14
13
  import PLUGINS_COMPONENTS from 'src/plugins'
15
- import { type PageContentType, getPage } from 'src/server/cms'
14
+ import type { PageContentType } from 'src/server/cms'
16
15
  import { injectGlobalSections } from 'src/server/cms/global'
16
+ import { contentService } from 'src/server/content/service'
17
+ import type { PreviewData } from 'src/server/content/types'
17
18
 
18
19
  /* A list of components that can be used in the CMS. */
19
20
  const COMPONENTS: Record<string, ComponentType<any>> = {
@@ -55,7 +56,7 @@ function Page({ page: { sections }, globalSections }: Props) {
55
56
  export const getStaticProps: GetStaticProps<
56
57
  Props,
57
58
  Record<string, string>,
58
- Locator
59
+ PreviewData
59
60
  > = async ({ previewData }) => {
60
61
  const [
61
62
  globalSectionsPromise,
@@ -65,9 +66,9 @@ export const getStaticProps: GetStaticProps<
65
66
 
66
67
  const [page, globalSections, globalSectionsHeader, globalSectionsFooter] =
67
68
  await Promise.all([
68
- getPage<PageContentType>({
69
- ...(previewData?.contentType === '404' && previewData),
69
+ contentService.getSingleContent<PageContentType>({
70
70
  contentType: '404',
71
+ previewData,
71
72
  }),
72
73
  globalSectionsPromise,
73
74
  globalSectionsHeaderPromise,
package/src/pages/500.tsx CHANGED
@@ -1,4 +1,3 @@
1
- import type { Locator } from '@vtex/client-cms'
2
1
  import type { GetStaticProps } from 'next'
3
2
  import { NextSeo } from 'next-seo'
4
3
  import type { ComponentType } from 'react'
@@ -12,8 +11,10 @@ import RenderSections from 'src/components/cms/RenderSections'
12
11
  import { OverriddenDefaultEmptyState as EmptyState } from 'src/components/sections/EmptyState/OverriddenDefaultEmptyState'
13
12
  import CUSTOM_COMPONENTS from 'src/customizations/src/components'
14
13
  import PLUGINS_COMPONENTS from 'src/plugins'
15
- import { type PageContentType, getPage } from 'src/server/cms'
14
+ import type { PageContentType } from 'src/server/cms'
16
15
  import { injectGlobalSections } from 'src/server/cms/global'
16
+ import { contentService } from 'src/server/content/service'
17
+ import type { PreviewData } from 'src/server/content/types'
17
18
 
18
19
  /* A list of components that can be used in the CMS. */
19
20
  const COMPONENTS: Record<string, ComponentType<any>> = {
@@ -56,7 +57,7 @@ function Page({ page: { sections }, globalSections }: Props) {
56
57
  export const getStaticProps: GetStaticProps<
57
58
  Props,
58
59
  Record<string, string>,
59
- Locator
60
+ PreviewData
60
61
  > = async ({ previewData }) => {
61
62
  const [
62
63
  globalSectionsPromise,
@@ -66,9 +67,9 @@ export const getStaticProps: GetStaticProps<
66
67
 
67
68
  const [page, globalSections, globalSectionsHeader, globalSectionsFooter] =
68
69
  await Promise.all([
69
- getPage<PageContentType>({
70
- ...(previewData?.contentType === '500' && previewData),
70
+ contentService.getSingleContent<PageContentType>({
71
71
  contentType: '500',
72
+ previewData,
72
73
  }),
73
74
  globalSectionsPromise,
74
75
  globalSectionsHeaderPromise,
@@ -12,7 +12,6 @@ import type {
12
12
  import { execute } from 'src/server'
13
13
 
14
14
  import type { SearchState } from '@faststore/sdk'
15
- import type { Locator } from '@vtex/client-cms'
16
15
  import dynamic from 'next/dynamic'
17
16
  import {
18
17
  getGlobalSectionsData,
@@ -28,9 +27,11 @@ import ProductListingPage, {
28
27
  import { getRedirect } from 'src/sdk/redirects'
29
28
  import type { PageContentType } from 'src/server/cms'
30
29
  import { injectGlobalSections } from 'src/server/cms/global'
31
- import { getPLP, type PLPContentType } from 'src/server/cms/plp'
30
+ import type { PLPContentType } from 'src/server/cms/plp'
32
31
  import { getDynamicContent } from 'src/utils/dynamicContent'
33
32
  import { fetchServerManyProducts } from 'src/utils/fetchProductGallerySSR'
33
+ import { contentService } from 'src/server/content/service'
34
+ import type { PreviewData } from 'src/server/content/types'
34
35
 
35
36
  const LandingPage = dynamic(
36
37
  () => import('src/components/templates/LandingPage')
@@ -103,7 +104,7 @@ const query = gql(`
103
104
  export const getStaticProps: GetStaticProps<
104
105
  Props,
105
106
  { slug: string[] },
106
- Locator
107
+ PreviewData
107
108
  > = async ({ params, previewData }) => {
108
109
  const slug = params?.slug.join('/') ?? ''
109
110
  const rewrites = (await storeConfig.rewrites?.()) ?? []
@@ -162,7 +163,13 @@ export const getStaticProps: GetStaticProps<
162
163
  variables: { slug },
163
164
  operation: query,
164
165
  }),
165
- getPLP(slug, previewData, rewrites),
166
+ contentService.getPlpContent(
167
+ {
168
+ previewData,
169
+ slug,
170
+ },
171
+ rewrites
172
+ ),
166
173
  globalSectionsPromise,
167
174
  globalSectionsHeaderPromise,
168
175
  globalSectionsFooterPromise,
@@ -1,5 +1,4 @@
1
1
  import { isNotFoundError } from '@faststore/api'
2
- import type { Locator } from '@vtex/client-cms'
3
2
  import deepmerge from 'deepmerge'
4
3
  import type { GetStaticPaths, GetStaticProps } from 'next'
5
4
  import { BreadcrumbJsonLd, NextSeo, ProductJsonLd } from 'next-seo'
@@ -37,7 +36,9 @@ import { getOfferUrl, useOffer } from 'src/sdk/offer'
37
36
  import PageProvider, { type PDPContext } from 'src/sdk/overrides/PageProvider'
38
37
  import { useProductQuery } from 'src/sdk/product/useProductQuery'
39
38
  import { injectGlobalSections } from 'src/server/cms/global'
40
- import { getPDP, type PDPContentType } from 'src/server/cms/pdp'
39
+ import type { PDPContentType } from 'src/server/cms/pdp'
40
+ import { contentService } from 'src/server/content/service'
41
+ import type { PreviewData } from 'src/server/content/types'
41
42
 
42
43
  type StoreConfig = typeof storeConfig & {
43
44
  experimental: {
@@ -90,8 +91,9 @@ function Page({
90
91
  offers,
91
92
  meta,
92
93
  }: Props) {
93
- const { product } = server
94
94
  const { currency } = useSession()
95
+
96
+ const { product } = server
95
97
  const {
96
98
  seo: { pdp: pdpSeo, ...storeSeo },
97
99
  } = storeConfig
@@ -183,7 +185,9 @@ function Page({
183
185
  <BreadcrumbJsonLd itemListElements={itemListElements} />
184
186
  <ProductJsonLd
185
187
  id={`${meta.canonical}${settings?.seo?.id ?? ''}`}
186
- mainEntityOfPage={`${meta.canonical}${settings?.seo?.mainEntityOfPage ?? ''}`}
188
+ mainEntityOfPage={`${meta.canonical}${
189
+ settings?.seo?.mainEntityOfPage ?? ''
190
+ }`}
187
191
  productName={product.name}
188
192
  description={product.description}
189
193
  brand={product.brand.name}
@@ -283,7 +287,7 @@ const query = gql(`
283
287
  export const getStaticProps: GetStaticProps<
284
288
  Props,
285
289
  { slug: string },
286
- Locator
290
+ PreviewData
287
291
  > = async ({ params, previewData }) => {
288
292
  const slug = params?.slug ?? ''
289
293
 
@@ -333,7 +337,13 @@ export const getStaticProps: GetStaticProps<
333
337
  throw errors[0]
334
338
  }
335
339
 
336
- const cmsPage: PDPContentType = await getPDP(data.product, previewData)
340
+ const cmsPage: PDPContentType = await contentService.getPdpContent(
341
+ data.product,
342
+ {
343
+ previewData,
344
+ slug,
345
+ }
346
+ )
337
347
 
338
348
  const { seo } = data.product
339
349
  const title = seo.title
@@ -3,17 +3,19 @@ import type { AppProps } from 'next/app'
3
3
  import Layout from 'src/Layout'
4
4
  import AnalyticsHandler from 'src/sdk/analytics'
5
5
  import ErrorBoundary from 'src/sdk/error/ErrorBoundary'
6
+ import useGeolocation from 'src/sdk/geolocation/useGeolocation'
6
7
  import SEO from '../../next-seo.config'
7
8
 
8
9
  // FastStore UI's base styles
9
- import '../styles/global/index.scss'
10
- import '../plugins/index.scss'
11
10
  import '../customizations/src/themes/index.scss'
11
+ import '../plugins/index.scss'
12
+ import '../styles/global/index.scss'
12
13
 
13
14
  import { DefaultSeo } from 'next-seo'
14
15
 
15
16
  function App({ Component, pageProps }: AppProps) {
16
17
  const { key } = pageProps
18
+ useGeolocation()
17
19
 
18
20
  return (
19
21
  <ErrorBoundary>
@@ -1,8 +1,9 @@
1
1
  import type { NextApiHandler, NextApiRequest } from 'next'
2
- import type { Locator } from '@vtex/client-cms'
3
2
 
4
- import { clientCMS } from 'src/server/cms'
5
3
  import { previewRedirects } from '../../../discovery.config'
4
+ import { contentService } from 'src/server/content/service'
5
+ import { isLocator } from 'src/server/cms'
6
+ import { isContentPlatformSource } from 'src/server/content/utils'
6
7
 
7
8
  type Settings = {
8
9
  seo: {
@@ -22,17 +23,29 @@ class StatusError extends Error {
22
23
 
23
24
  const pickParam = (req: NextApiRequest, parameter: string) => {
24
25
  const maybeParam = req.query[parameter]
26
+ return typeof maybeParam === 'string' ? maybeParam : undefined
27
+ }
25
28
 
26
- if (typeof maybeParam !== 'string') {
27
- return undefined
28
- }
29
-
30
- return maybeParam
29
+ const setPreviewAndRedirect = (
30
+ res: any,
31
+ previewData: Record<string, string>,
32
+ redirectPath: string
33
+ ) => {
34
+ res.setPreviewData(previewData, {
35
+ maxAge: 3600,
36
+ path: redirectPath,
37
+ })
38
+ res.redirect(redirectPath)
31
39
  }
32
40
 
33
41
  // TODO: Improve security by disabling CMS preview in production
34
42
  const handler: NextApiHandler = async (req, res) => {
35
43
  try {
44
+ let slug = pickParam(req, 'slug')
45
+ if (slug && !slug.startsWith('/')) {
46
+ slug = `/${slug}`
47
+ }
48
+
36
49
  const locator = [
37
50
  'contentType',
38
51
  'documentId',
@@ -65,8 +78,19 @@ const handler: NextApiHandler = async (req, res) => {
65
78
  )
66
79
  }
67
80
 
81
+ if (!isLocator(locator)) {
82
+ throw new StatusError('Invalid locator object', 400)
83
+ }
84
+
68
85
  // Fetch CMS to check if the provided `locator` exists
69
- const page = await clientCMS.getCMSPage(locator as Locator)
86
+ const page = await contentService.getSingleContent({
87
+ contentType: locator.contentType,
88
+ previewData: locator,
89
+ slug,
90
+ documentId: locator.documentId,
91
+ versionId: locator.versionId,
92
+ releaseId: locator.releaseId,
93
+ })
70
94
 
71
95
  // If the content doesn't exist prevent preview mode from being enabled
72
96
  if (!page) {
@@ -76,25 +100,26 @@ const handler: NextApiHandler = async (req, res) => {
76
100
  )
77
101
  }
78
102
 
79
- // Enable Preview Mode by setting the cookies
80
- res.setPreviewData(locator, {
81
- maxAge: 3600,
82
- path: (page.settings as Settings)?.seo?.slug,
83
- })
103
+ if (
104
+ isContentPlatformSource() &&
105
+ slug &&
106
+ ['landingPage', 'plp', 'pdp'].includes(locator.contentType)
107
+ ) {
108
+ return setPreviewAndRedirect(res, locator, slug)
109
+ }
84
110
 
85
111
  // Redirect to the path from the fetched locator
86
112
  const redirects = previewRedirects as Record<string, string>
87
113
  if (redirects[locator.contentType]) {
88
- res.redirect(redirects[locator.contentType])
89
- return
114
+ return setPreviewAndRedirect(res, locator, redirects[locator.contentType])
90
115
  }
91
116
 
92
117
  if (locator.contentType === 'landingPage') {
93
- res.redirect(`${(page.settings as Settings)?.seo.slug}`)
94
- return
118
+ slug = (page.settings as Settings)?.seo?.slug
119
+ return setPreviewAndRedirect(res, locator, slug)
95
120
  }
96
121
 
97
- res.redirect('/')
122
+ return setPreviewAndRedirect(res, locator, '/')
98
123
  } catch (error) {
99
124
  if (error instanceof StatusError) {
100
125
  res.status(error.status).end(error.message)
@@ -1,10 +1,8 @@
1
- import type { Locator } from '@vtex/client-cms'
2
1
  import type { GetStaticProps } from 'next'
3
2
  import { NextSeo, OrganizationJsonLd, SiteLinksSearchBoxJsonLd } from 'next-seo'
4
3
 
5
4
  import RenderSections from 'src/components/cms/RenderSections'
6
5
  import type { PageContentType } from 'src/server/cms'
7
- import { getPage } from 'src/server/cms'
8
6
 
9
7
  import {
10
8
  type GlobalSectionsData,
@@ -15,6 +13,8 @@ import PageProvider from 'src/sdk/overrides/PageProvider'
15
13
  import { injectGlobalSections } from 'src/server/cms/global'
16
14
  import { getDynamicContent } from 'src/utils/dynamicContent'
17
15
  import storeConfig from '../../discovery.config'
16
+ import { contentService } from 'src/server/content/service'
17
+ import type { PreviewData } from 'src/server/content/types'
18
18
 
19
19
  type Props = {
20
20
  page: PageContentType
@@ -146,14 +146,13 @@ function Page({
146
146
  export const getStaticProps: GetStaticProps<
147
147
  Props,
148
148
  Record<string, string>,
149
- Locator
149
+ PreviewData
150
150
  > = async ({ previewData }) => {
151
151
  const [
152
152
  globalSectionsPromise,
153
153
  globalSectionsHeaderPromise,
154
154
  globalSectionsFooterPromise,
155
155
  ] = getGlobalSectionsData(previewData)
156
-
157
156
  const serverDataPromise = getDynamicContent({ pageType: 'home' })
158
157
 
159
158
  let cmsPage = null
@@ -161,15 +160,18 @@ export const getStaticProps: GetStaticProps<
161
160
  const cmsData = JSON.parse(storeConfig.cms.data)
162
161
  cmsPage = cmsData['home'][0]
163
162
  }
163
+
164
164
  const pagePromise = cmsPage
165
- ? getPage<PageContentType>({
165
+ ? contentService.getSingleContent<PageContentType>({
166
166
  contentType: 'home',
167
+ previewData,
167
168
  documentId: cmsPage.documentId,
168
169
  versionId: cmsPage.versionId,
170
+ releaseId: cmsPage.releaseId,
169
171
  })
170
- : getPage<PageContentType>({
171
- ...(previewData?.contentType === 'home' && previewData),
172
+ : contentService.getSingleContent<PageContentType>({
172
173
  contentType: 'home',
174
+ previewData,
173
175
  })
174
176
 
175
177
  const [
@@ -2,7 +2,6 @@ import { NextSeo } from 'next-seo'
2
2
  import type { ComponentType } from 'react'
3
3
  import { useEffect } from 'react'
4
4
 
5
- import type { Locator } from '@vtex/client-cms'
6
5
  import type { GetStaticProps } from 'next'
7
6
  import { default as GLOBAL_COMPONENTS } from 'src/components/cms/global/Components'
8
7
  import {
@@ -13,9 +12,11 @@ import RenderSections from 'src/components/cms/RenderSections'
13
12
  import { OverriddenDefaultEmptyState as EmptyState } from 'src/components/sections/EmptyState/OverriddenDefaultEmptyState'
14
13
  import CUSTOM_COMPONENTS from 'src/customizations/src/components'
15
14
  import PLUGINS_COMPONENTS from 'src/plugins'
16
- import { type PageContentType, getPage } from 'src/server/cms'
15
+ import type { PageContentType } from 'src/server/cms'
17
16
  import { injectGlobalSections } from 'src/server/cms/global'
18
17
  import storeConfig from '../../discovery.config'
18
+ import { contentService } from 'src/server/content/service'
19
+ import type { PreviewData } from 'src/server/content/types'
19
20
 
20
21
  /* A list of components that can be used in the CMS. */
21
22
  const COMPONENTS: Record<string, ComponentType<any>> = {
@@ -68,7 +69,7 @@ function Page({ page: { sections }, globalSections }: Props) {
68
69
  export const getStaticProps: GetStaticProps<
69
70
  Props,
70
71
  Record<string, string>,
71
- Locator
72
+ PreviewData
72
73
  > = async ({ previewData }) => {
73
74
  const [
74
75
  globalSectionsPromise,
@@ -78,9 +79,9 @@ export const getStaticProps: GetStaticProps<
78
79
 
79
80
  const [page, globalSections, globalSectionsHeader, globalSectionsFooter] =
80
81
  await Promise.all([
81
- getPage<PageContentType>({
82
- ...(previewData?.contentType === 'login' && previewData),
82
+ contentService.getSingleContent<PageContentType>({
83
83
  contentType: 'login',
84
+ previewData,
84
85
  }),
85
86
  globalSectionsPromise,
86
87
  globalSectionsHeaderPromise,
@@ -1,12 +1,14 @@
1
1
  import type { Options } from 'src/server/cms'
2
+ import type { EntryPathParams } from '@vtex/client-cp'
3
+ import { contentSource } from 'discovery.config.default'
2
4
 
3
5
  export default class MissingContentError extends Error {
4
- constructor(options: Options) {
6
+ constructor(params: Options | EntryPathParams) {
5
7
  super(
6
- `Missing content on the CMS for content type ${
7
- options.contentType
8
+ `Missing content on the ${contentSource.type} for content type ${
9
+ params.contentType
8
10
  }. Add content before proceeding. Context: ${JSON.stringify(
9
- options,
11
+ params,
10
12
  null,
11
13
  2
12
14
  )}`