create-sitecore-jss 20.0.0-canary.78

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 (166) hide show
  1. package/LICENSE.MD +202 -0
  2. package/dist/InitializerFactory.js +49 -0
  3. package/dist/common/Initializer.js +2 -0
  4. package/dist/common/args/base.js +2 -0
  5. package/dist/common/args/styleguide.js +2 -0
  6. package/dist/common/prompts/base.js +40 -0
  7. package/dist/common/prompts/styleguide.js +28 -0
  8. package/dist/common/steps/index.js +13 -0
  9. package/dist/common/steps/install.js +46 -0
  10. package/dist/common/steps/next.js +60 -0
  11. package/dist/common/steps/transform.js +185 -0
  12. package/dist/common/utils/cmd.js +39 -0
  13. package/dist/common/utils/helpers.js +92 -0
  14. package/dist/index.js +91 -0
  15. package/dist/init-runner.js +50 -0
  16. package/dist/initializers/nextjs/args.js +2 -0
  17. package/dist/initializers/nextjs/index.js +65 -0
  18. package/dist/initializers/nextjs/prompts.js +19 -0
  19. package/dist/initializers/nextjs/remove-dev-dependencies.js +24 -0
  20. package/dist/initializers/nextjs-styleguide/index.js +49 -0
  21. package/dist/templates/nextjs/.env +49 -0
  22. package/dist/templates/nextjs/.eslintrc +25 -0
  23. package/dist/templates/nextjs/.gitattributes +11 -0
  24. package/dist/templates/nextjs/.gitignore +33 -0
  25. package/dist/templates/nextjs/.graphql-let.yml +10 -0
  26. package/dist/templates/nextjs/.prettierignore +1 -0
  27. package/dist/templates/nextjs/.prettierrc +8 -0
  28. package/dist/templates/nextjs/LICENSE.txt +202 -0
  29. package/dist/templates/nextjs/README.md +3 -0
  30. package/dist/templates/nextjs/next-env.d.ts +6 -0
  31. package/dist/templates/nextjs/next.config.js +56 -0
  32. package/dist/templates/nextjs/package.json +88 -0
  33. package/dist/templates/nextjs/public/favicon.ico +0 -0
  34. package/dist/templates/nextjs/public/sc_logo.svg +20 -0
  35. package/dist/templates/nextjs/scripts/bootstrap.ts +40 -0
  36. package/dist/templates/nextjs/scripts/fetch-graphql-introspection-data.ts +49 -0
  37. package/dist/templates/nextjs/scripts/generate-component-factory.ts +95 -0
  38. package/dist/templates/nextjs/scripts/generate-config.ts +85 -0
  39. package/dist/templates/nextjs/scripts/generate-plugins.ts +103 -0
  40. package/dist/templates/nextjs/scripts/scaffold-component.ts +89 -0
  41. package/dist/templates/nextjs/scripts/templates/component-factory.ts +119 -0
  42. package/dist/templates/nextjs/scripts/templates/component-src.ts +27 -0
  43. package/dist/templates/nextjs/scripts/utils.ts +59 -0
  44. package/dist/templates/nextjs/sitecore/config/{{appName}}.config +151 -0
  45. package/dist/templates/nextjs/src/Layout.tsx +53 -0
  46. package/dist/templates/nextjs/src/Navigation.tsx +27 -0
  47. package/dist/templates/nextjs/src/NotFound.tsx +19 -0
  48. package/dist/templates/nextjs/src/assets/app.css +28 -0
  49. package/dist/templates/nextjs/src/components/ContentBlock.tsx +24 -0
  50. package/dist/templates/nextjs/src/lib/component-props/index.ts +23 -0
  51. package/dist/templates/nextjs/src/lib/data-fetcher.ts +16 -0
  52. package/dist/templates/nextjs/src/lib/dictionary-service-factory.ts +30 -0
  53. package/dist/templates/nextjs/src/lib/layout-service-factory.ts +25 -0
  54. package/dist/templates/nextjs/src/lib/next-config/plugins/graphql.js +32 -0
  55. package/dist/templates/nextjs/src/lib/next-config/plugins/monorepo.js +27 -0
  56. package/dist/templates/nextjs/src/lib/page-props-factory/index.ts +50 -0
  57. package/dist/templates/nextjs/src/lib/page-props-factory/plugins/componentProps.ts +38 -0
  58. package/dist/templates/nextjs/src/lib/page-props-factory/plugins/normalMode.ts +75 -0
  59. package/dist/templates/nextjs/src/lib/page-props-factory/plugins/previewMode.ts +27 -0
  60. package/dist/templates/nextjs/src/lib/page-props.ts +16 -0
  61. package/dist/templates/nextjs/src/lib/sitemap-fetcher/index.ts +25 -0
  62. package/dist/templates/nextjs/src/lib/sitemap-fetcher/plugins/graphqlSitemapService.ts +36 -0
  63. package/dist/templates/nextjs/src/pages/404.tsx +5 -0
  64. package/dist/templates/nextjs/src/pages/[[...path]].tsx +91 -0
  65. package/dist/templates/nextjs/src/pages/_app.tsx +19 -0
  66. package/dist/templates/nextjs/src/pages/_error.tsx +35 -0
  67. package/dist/templates/nextjs/src/pages/api/editing/data/[key].ts +24 -0
  68. package/dist/templates/nextjs/src/pages/api/editing/render.ts +30 -0
  69. package/dist/templates/nextjs/src/temp/.gitignore +3 -0
  70. package/dist/templates/nextjs/src/temp/GraphQLIntrospectionResult.json +22216 -0
  71. package/dist/templates/nextjs/tsconfig.json +42 -0
  72. package/dist/templates/nextjs/tsconfig.scripts.json +6 -0
  73. package/dist/templates/nextjs-styleguide/data/component-content/.gitignore +0 -0
  74. package/dist/templates/nextjs-styleguide/data/component-content/Styleguide/ContentReuse/LoremIpsumContentBlock/en.yml +9 -0
  75. package/dist/templates/nextjs-styleguide/data/content/.gitignore +0 -0
  76. package/dist/templates/nextjs-styleguide/data/content/Styleguide/ContentListField/Item1/en.yml +6 -0
  77. package/dist/templates/nextjs-styleguide/data/content/Styleguide/ContentListField/Item2/en.yml +6 -0
  78. package/dist/templates/nextjs-styleguide/data/content/Styleguide/ItemLinkField/Item1/en.yml +6 -0
  79. package/dist/templates/nextjs-styleguide/data/content/Styleguide/ItemLinkField/Item2/en.yml +6 -0
  80. package/dist/templates/nextjs-styleguide/data/dictionary/en.yml +4 -0
  81. package/dist/templates/nextjs-styleguide/data/dictionary/{{language}}.yml +4 -0
  82. package/dist/templates/nextjs-styleguide/data/media/files/jss.pdf +0 -0
  83. package/dist/templates/nextjs-styleguide/data/media/img/jss_logo.png +0 -0
  84. package/dist/templates/nextjs-styleguide/data/media/img/sc_logo.png +0 -0
  85. package/dist/templates/nextjs-styleguide/data/routes/en.yml +63 -0
  86. package/dist/templates/nextjs-styleguide/data/routes/graphql/en.yml +27 -0
  87. package/dist/templates/nextjs-styleguide/data/routes/graphql/sample-1/en.yml +9 -0
  88. package/dist/templates/nextjs-styleguide/data/routes/graphql/sample-2/en.yml +9 -0
  89. package/dist/templates/nextjs-styleguide/data/routes/styleguide/custom-route-type/en.yml +12 -0
  90. package/dist/templates/nextjs-styleguide/data/routes/styleguide/en.yml +246 -0
  91. package/dist/templates/nextjs-styleguide/data/routes/styleguide/{{language}}.yml +25 -0
  92. package/dist/templates/nextjs-styleguide/data/routes/{{language}}.yml +4 -0
  93. package/dist/templates/nextjs-styleguide/package.json +13 -0
  94. package/dist/templates/nextjs-styleguide/scripts/disconnected-mode-proxy.ts +48 -0
  95. package/dist/templates/nextjs-styleguide/scripts/scaffold-component.ts +130 -0
  96. package/dist/templates/nextjs-styleguide/scripts/templates/component-manifest.ts +30 -0
  97. package/dist/templates/nextjs-styleguide/sitecore/definitions/component-content.sitecore.ts +117 -0
  98. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/ContentBlock.sitecore.ts +19 -0
  99. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-Checkbox.sitecore.ts +23 -0
  100. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-ContentList.sitecore.ts +32 -0
  101. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-Custom.sitecore.ts +23 -0
  102. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-Date.sitecore.ts +23 -0
  103. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-File.sitecore.ts +20 -0
  104. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-Image.sitecore.ts +23 -0
  105. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-ItemLink.sitecore.ts +32 -0
  106. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-Link.sitecore.ts +25 -0
  107. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-Number.sitecore.ts +20 -0
  108. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-RichText.sitecore.ts +28 -0
  109. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/fields/Styleguide-FieldUsage-Text.sitecore.ts +28 -0
  110. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/graphql/GraphQL-ConnectedDemo.sitecore.ts +18 -0
  111. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/graphql/GraphQL-IntegratedDemo.sitecore.graphql +71 -0
  112. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/graphql/GraphQL-IntegratedDemo.sitecore.ts +25 -0
  113. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/graphql/GraphQL-Layout.sitecore.ts +15 -0
  114. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-ComponentParams.sitecore.ts +20 -0
  115. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-CustomRouteType.sitecore.ts +31 -0
  116. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-Layout-Reuse.sitecore.ts +20 -0
  117. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-Layout-Tabs-Tab.sitecore.ts +23 -0
  118. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-Layout-Tabs.sitecore.ts +20 -0
  119. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-Layout.sitecore.ts +15 -0
  120. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-Multilingual.sitecore.ts +26 -0
  121. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-RouteFields.sitecore.ts +22 -0
  122. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-Section.sitecore.ts +16 -0
  123. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-SitecoreContext.sitecore.ts +19 -0
  124. package/dist/templates/nextjs-styleguide/sitecore/definitions/components/styleguide/Styleguide-Tracking.sitecore.ts +19 -0
  125. package/dist/templates/nextjs-styleguide/sitecore/definitions/config.js +5 -0
  126. package/dist/templates/nextjs-styleguide/sitecore/definitions/content.sitecore.ts +117 -0
  127. package/dist/templates/nextjs-styleguide/sitecore/definitions/dictionary.sitecore.ts +52 -0
  128. package/dist/templates/nextjs-styleguide/sitecore/definitions/placeholders.sitecore.ts +21 -0
  129. package/dist/templates/nextjs-styleguide/sitecore/definitions/routes.sitecore.ts +88 -0
  130. package/dist/templates/nextjs-styleguide/sitecore/definitions/templates/Styleguide-ContentList-Template.sitecore.ts +12 -0
  131. package/dist/templates/nextjs-styleguide/sitecore/definitions/templates/Styleguide-Explanatory-Component.sitecore.ts +20 -0
  132. package/dist/templates/nextjs-styleguide/sitecore/definitions/templates/Styleguide-ItemLink-Template.sitecore.ts +13 -0
  133. package/dist/templates/nextjs-styleguide/src/Navigation.tsx +41 -0
  134. package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-Checkbox.tsx +52 -0
  135. package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-ContentList.tsx +58 -0
  136. package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-Custom.tsx +25 -0
  137. package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-Date.tsx +55 -0
  138. package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-File.tsx +30 -0
  139. package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-Image.tsx +58 -0
  140. package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-ItemLink.tsx +50 -0
  141. package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-Link.tsx +46 -0
  142. package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-Number.tsx +34 -0
  143. package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-RichText.tsx +35 -0
  144. package/dist/templates/nextjs-styleguide/src/components/fields/Styleguide-FieldUsage-Text.tsx +43 -0
  145. package/dist/templates/nextjs-styleguide/src/components/graphql/GraphQL-ConnectedDemo.dynamic.graphql +69 -0
  146. package/dist/templates/nextjs-styleguide/src/components/graphql/GraphQL-ConnectedDemo.dynamic.tsx +148 -0
  147. package/dist/templates/nextjs-styleguide/src/components/graphql/GraphQL-IntegratedDemo.tsx +130 -0
  148. package/dist/templates/nextjs-styleguide/src/components/graphql/GraphQL-Layout.tsx +37 -0
  149. package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-ComponentParams.tsx +47 -0
  150. package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-CustomRouteType.tsx +37 -0
  151. package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Layout-Reuse.tsx +45 -0
  152. package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Layout-Tabs-Tab.tsx +41 -0
  153. package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Layout-Tabs.tsx +111 -0
  154. package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Layout.tsx +68 -0
  155. package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Multilingual.tsx +50 -0
  156. package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-RouteFields.tsx +37 -0
  157. package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Section.tsx +22 -0
  158. package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-SitecoreContext.tsx +25 -0
  159. package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Specimen.tsx +41 -0
  160. package/dist/templates/nextjs-styleguide/src/components/styleguide/Styleguide-Tracking.tsx +341 -0
  161. package/dist/templates/nextjs-styleguide/src/lib/component-props/styleguide.ts +11 -0
  162. package/dist/templates/nextjs-styleguide/src/lib/next-config/plugins/disconnected.js +43 -0
  163. package/dist/templates/nextjs-styleguide/src/lib/next-config/plugins/styleguide.js +10 -0
  164. package/dist/templates/nextjs-styleguide/src/lib/sitemap-fetcher/plugins/disconnectedSitemapService.ts +46 -0
  165. package/dist/templates/nextjs-styleguide/src/pages/_app.tsx +33 -0
  166. package/package.json +61 -0
@@ -0,0 +1,27 @@
1
+ import { getPublicUrl } from '@sitecore-jss/sitecore-jss-nextjs';
2
+
3
+ // Prefix public assets with a public URL to enable compatibility with Sitecore Experience Editor.
4
+ // If you're not supporting the Experience Editor, you can remove this.
5
+ const publicUrl = getPublicUrl();
6
+
7
+ const Navigation = (): JSX.Element => (
8
+ <div>
9
+ <nav>
10
+ <ul>
11
+ <li>
12
+ <a href="https://sitecore.com">
13
+ <img src={`${publicUrl}/sc_logo.svg`} alt="Sitecore" />
14
+ </a>
15
+ </li>
16
+ <li>
17
+ <a href="https://jss.sitecore.com">JSS Documentation</a>
18
+ </li>
19
+ <li>
20
+ <a href="https://github.com/Sitecore/jss">JSS Repository</a>
21
+ </li>
22
+ </ul>
23
+ </nav>
24
+ </div>
25
+ );
26
+
27
+ export default Navigation;
@@ -0,0 +1,19 @@
1
+ import Head from 'next/head';
2
+
3
+ /**
4
+ * Rendered in case if we have 404 error
5
+ */
6
+ const NotFound = (): JSX.Element => (
7
+ <>
8
+ <Head>
9
+ <title>404: NotFound</title>
10
+ </Head>
11
+ <div style={{ padding: 10 }}>
12
+ <h1>Page not found</h1>
13
+ <p>This page does not exist.</p>
14
+ <a href="/">Go to the Home page</a>
15
+ </div>
16
+ </>
17
+ );
18
+
19
+ export default NotFound;
@@ -0,0 +1,28 @@
1
+ a[target='_blank']:after {
2
+ content: '\1F5D7'
3
+ }
4
+
5
+ /*
6
+ Hides Sitecore Experience Editor markup,
7
+ if you run the app in connected mode while the Sitecore cookies
8
+ are set to edit mode.
9
+ */
10
+ .scChromeData, .scpm { display: none !important; }
11
+
12
+ /*
13
+ Styles for default JSS error components
14
+ */
15
+ .sc-jss-editing-error,
16
+ .sc-jss-placeholder-error {
17
+ padding: 1em;
18
+ background-color: lightyellow;
19
+ }
20
+
21
+ /*
22
+ Style for default content block
23
+ */
24
+ .contentTitle {
25
+ font-size: 3.5rem;
26
+ font-weight: 300;
27
+ line-height: 1.2;
28
+ }
@@ -0,0 +1,24 @@
1
+ import { Text, RichText, Field, withDatasourceCheck } from '@sitecore-jss/sitecore-jss-nextjs';
2
+ import { ComponentProps } from 'lib/component-props';
3
+
4
+ type ContentBlockProps = ComponentProps & {
5
+ fields: {
6
+ heading: Field<string>;
7
+ content: Field<string>;
8
+ };
9
+ };
10
+
11
+ /**
12
+ * A simple Content Block component, with a heading and rich text block.
13
+ * This is the most basic building block of a content site, and the most basic
14
+ * JSS component that's useful.
15
+ */
16
+ const ContentBlock = ({ fields }: ContentBlockProps): JSX.Element => (
17
+ <div className="contentBlock">
18
+ <Text tag="h2" className="contentTitle" field={fields.heading} />
19
+
20
+ <RichText className="contentDescription" field={fields.content} />
21
+ </div>
22
+ );
23
+
24
+ export default withDatasourceCheck()<ContentBlockProps>(ContentBlock);
@@ -0,0 +1,23 @@
1
+ import {
2
+ ComponentParams,
3
+ ComponentRendering,
4
+ SitecoreContextValue,
5
+ } from '@sitecore-jss/sitecore-jss-nextjs';
6
+
7
+ /**
8
+ * Shared component props
9
+ */
10
+ export type ComponentProps = {
11
+ rendering: ComponentRendering;
12
+ params: ComponentParams;
13
+ };
14
+
15
+ /**
16
+ * Component props with context
17
+ * You can access `sitecoreContext` by withSitecoreContext/useSitecoreContext
18
+ * @example withSitecoreContext()(ContentBlock)
19
+ * @example const { sitecoreContext } = useSitecoreContext()
20
+ */
21
+ export type ComponentWithContextProps = ComponentProps & {
22
+ sitecoreContext: SitecoreContextValue;
23
+ };
@@ -0,0 +1,16 @@
1
+ import { AxiosResponse } from 'axios';
2
+ import { AxiosDataFetcher } from '@sitecore-jss/sitecore-jss-nextjs';
3
+
4
+ /**
5
+ * Implements a data fetcher using Axios - replace with your favorite
6
+ * SSR-capable HTTP or fetch library if you like. See HttpDataFetcher<T> type
7
+ * in sitecore-jss library for implementation details/notes.
8
+ * @param {string} url The URL to request; may include query string
9
+ * @param {unknown} data Optional data to POST with the request.
10
+ */
11
+ export function dataFetcher<ResponseType>(
12
+ url: string,
13
+ data?: unknown
14
+ ): Promise<AxiosResponse<ResponseType>> {
15
+ return new AxiosDataFetcher().fetch<ResponseType>(url, data);
16
+ }
@@ -0,0 +1,30 @@
1
+ import {
2
+ DictionaryService,
3
+ RestDictionaryService,
4
+ GraphQLDictionaryService,
5
+ } from '@sitecore-jss/sitecore-jss-nextjs';
6
+ import config from 'temp/config';
7
+
8
+ export class DictionaryServiceFactory {
9
+ create(): DictionaryService {
10
+ return process.env.FETCH_WITH === 'GraphQL'
11
+ ? new GraphQLDictionaryService({
12
+ endpoint: config.graphQLEndpoint,
13
+ apiKey: config.sitecoreApiKey,
14
+ siteName: config.jssAppName,
15
+ /*
16
+ The Dictionary Service needs a root item ID in order to fetch dictionary phrases for the current
17
+ app. If your Sitecore instance only has 1 JSS App, you can specify the root item ID here;
18
+ otherwise, the service will attempt to figure out the root item for the current JSS App using GraphQL and app name.
19
+ rootItemId: '{GUID}'
20
+ */
21
+ })
22
+ : new RestDictionaryService({
23
+ apiHost: config.sitecoreApiHost,
24
+ apiKey: config.sitecoreApiKey,
25
+ siteName: config.jssAppName,
26
+ });
27
+ }
28
+ }
29
+
30
+ export const dictionaryServiceFactory = new DictionaryServiceFactory();
@@ -0,0 +1,25 @@
1
+ import {
2
+ LayoutService,
3
+ RestLayoutService,
4
+ GraphQLLayoutService,
5
+ } from '@sitecore-jss/sitecore-jss-nextjs';
6
+ import config from 'temp/config';
7
+
8
+ export class LayoutServiceFactory {
9
+ create(): LayoutService {
10
+ return process.env.FETCH_WITH === 'GraphQL'
11
+ ? new GraphQLLayoutService({
12
+ endpoint: config.graphQLEndpoint,
13
+ apiKey: config.sitecoreApiKey,
14
+ siteName: config.jssAppName,
15
+ })
16
+ : new RestLayoutService({
17
+ apiHost: config.sitecoreApiHost,
18
+ apiKey: config.sitecoreApiKey,
19
+ siteName: config.jssAppName,
20
+ configurationName: 'default',
21
+ });
22
+ }
23
+ }
24
+
25
+ export const layoutServiceFactory = new LayoutServiceFactory();
@@ -0,0 +1,32 @@
1
+ const graphqlPlugin = (nextConfig = {}) => {
2
+ return Object.assign({}, nextConfig, {
3
+ webpack: (config, options) => {
4
+ config.module.rules.push({
5
+ test: /\.graphql$/,
6
+ exclude: /node_modules/,
7
+ use: [options.defaultLoaders.babel, { loader: 'graphql-let/loader' }],
8
+ });
9
+
10
+ config.module.rules.push({
11
+ test: /\.graphqls$/,
12
+ exclude: /node_modules/,
13
+ use: ['graphql-let/schema/loader'],
14
+ });
15
+
16
+ config.module.rules.push({
17
+ test: /\.ya?ml$/,
18
+ type: 'json',
19
+ use: 'yaml-loader',
20
+ });
21
+
22
+ // Overload the Webpack config if it was already overloaded
23
+ if (typeof nextConfig.webpack === 'function') {
24
+ return nextConfig.webpack(config, options);
25
+ }
26
+
27
+ return config;
28
+ }
29
+ });
30
+ };
31
+
32
+ module.exports = graphqlPlugin;
@@ -0,0 +1,27 @@
1
+ const withTM = require('next-transpile-modules')(['@sitecore-jss/sitecore-jss-nextjs'], {
2
+ resolveSymlinks: false,
3
+ });
4
+ const path = require('path');
5
+
6
+ const CWD = process.cwd();
7
+
8
+ const monorepoPlugin = (nextConfig = {}) => {
9
+ return withTM(Object.assign({}, nextConfig, {
10
+ webpack: (config, options) => {
11
+ if (options.isServer) {
12
+ config.externals = ['react', 'vertx', ...config.externals];
13
+ }
14
+
15
+ config.resolve.alias['react'] = path.resolve(CWD, '.', 'node_modules', 'react');
16
+
17
+ // Overload the Webpack config if it was already overloaded
18
+ if (typeof nextConfig.webpack === 'function') {
19
+ return nextConfig.webpack(config, options);
20
+ }
21
+
22
+ return config;
23
+ }
24
+ }));
25
+ };
26
+
27
+ module.exports = monorepoPlugin;
@@ -0,0 +1,50 @@
1
+ import { GetServerSidePropsContext, GetStaticPropsContext } from 'next';
2
+ import { SitecorePageProps } from 'lib/page-props';
3
+ import * as plugins from 'temp/page-props-factory-plugins';
4
+
5
+ /**
6
+ * Determines whether context is GetServerSidePropsContext (SSR) or GetStaticPropsContext (SSG)
7
+ * @param {GetServerSidePropsContext | GetStaticPropsContext} context
8
+ */
9
+ export const isServerSidePropsContext = function (
10
+ context: GetServerSidePropsContext | GetStaticPropsContext
11
+ ): context is GetServerSidePropsContext {
12
+ return (<GetServerSidePropsContext>context).req !== undefined;
13
+ };
14
+
15
+ export interface Plugin {
16
+ /**
17
+ * Detect order when the plugin should be called, e.g. 0 - will be called first (can be a plugin which data is required for other plugins)
18
+ */
19
+ order: number;
20
+ /**
21
+ * A function which will be called during page props generation
22
+ */
23
+ exec(
24
+ props: SitecorePageProps,
25
+ context: GetServerSidePropsContext | GetStaticPropsContext
26
+ ): Promise<SitecorePageProps>;
27
+ }
28
+
29
+ export class SitecorePagePropsFactory {
30
+ /**
31
+ * Create SitecorePageProps for given context (SSR / GetServerSidePropsContext or SSG / GetStaticPropsContext)
32
+ * @param {GetServerSidePropsContext | GetStaticPropsContext} context
33
+ * @see SitecorePageProps
34
+ */
35
+ public async create(
36
+ context: GetServerSidePropsContext | GetStaticPropsContext
37
+ ): Promise<SitecorePageProps> {
38
+ const extendedProps = await (Object.values(plugins) as Plugin[])
39
+ .sort((p1, p2) => p1.order - p2.order)
40
+ .reduce(async (result, plugin) => {
41
+ const props = await result;
42
+ const newProps = await plugin.exec(props, context);
43
+ return newProps;
44
+ }, Promise.resolve({} as SitecorePageProps));
45
+
46
+ return extendedProps;
47
+ }
48
+ }
49
+
50
+ export const sitecorePagePropsFactory = new SitecorePagePropsFactory();
@@ -0,0 +1,38 @@
1
+ import { ComponentPropsService } from '@sitecore-jss/sitecore-jss-nextjs';
2
+ import { SitecorePageProps } from 'lib/page-props';
3
+ import { GetServerSidePropsContext, GetStaticPropsContext } from 'next';
4
+ import { componentModule } from 'temp/componentFactory';
5
+ import { Plugin, isServerSidePropsContext } from '..';
6
+
7
+ class ComponentPropsPlugin implements Plugin {
8
+ private componentPropsService: ComponentPropsService;
9
+
10
+ order = 1;
11
+
12
+ constructor() {
13
+ this.componentPropsService = new ComponentPropsService();
14
+ }
15
+
16
+ async exec(props: SitecorePageProps, context: GetServerSidePropsContext | GetStaticPropsContext) {
17
+ if (!props.layoutData.sitecore.route) return props;
18
+
19
+ // Retrieve component props using side-effects defined on components level
20
+ if (isServerSidePropsContext(context)) {
21
+ props.componentProps = await this.componentPropsService.fetchServerSideComponentProps({
22
+ layoutData: props.layoutData,
23
+ context,
24
+ componentModule,
25
+ });
26
+ } else {
27
+ props.componentProps = await this.componentPropsService.fetchStaticComponentProps({
28
+ layoutData: props.layoutData,
29
+ context,
30
+ componentModule,
31
+ });
32
+ }
33
+
34
+ return props;
35
+ }
36
+ }
37
+
38
+ export const componentPropsPlugin = new ComponentPropsPlugin();
@@ -0,0 +1,75 @@
1
+ import { ParsedUrlQuery } from 'querystring';
2
+ import { GetServerSidePropsContext, GetStaticPropsContext } from 'next';
3
+ import { DictionaryService, LayoutService } from '@sitecore-jss/sitecore-jss-nextjs';
4
+ import { dictionaryServiceFactory } from 'lib/dictionary-service-factory';
5
+ import { layoutServiceFactory } from 'lib/layout-service-factory';
6
+ import { SitecorePageProps } from 'lib/page-props';
7
+ import { Plugin, isServerSidePropsContext } from '..';
8
+ import pkg from '../../../../package.json';
9
+
10
+ /**
11
+ * Extract normalized Sitecore item path from query
12
+ * @param {ParsedUrlQuery | undefined} params
13
+ */
14
+ function extractPath(params: ParsedUrlQuery | undefined): string {
15
+ if (params === undefined) {
16
+ return '/';
17
+ }
18
+ let path = Array.isArray(params.path) ? params.path.join('/') : params.path ?? '/';
19
+
20
+ // Ensure leading '/'
21
+ if (!path.startsWith('/')) {
22
+ path = '/' + path;
23
+ }
24
+
25
+ return path;
26
+ }
27
+
28
+ class NormalModePlugin implements Plugin {
29
+ private dictionaryService: DictionaryService;
30
+ private layoutService: LayoutService;
31
+
32
+ order = 0;
33
+
34
+ constructor() {
35
+ this.dictionaryService = dictionaryServiceFactory.create();
36
+ this.layoutService = layoutServiceFactory.create();
37
+ }
38
+
39
+ async exec(props: SitecorePageProps, context: GetServerSidePropsContext | GetStaticPropsContext) {
40
+ if (context.preview) return props;
41
+
42
+ /**
43
+ * Normal mode
44
+ */
45
+ // Get normalized Sitecore item path
46
+ const path = extractPath(context.params);
47
+
48
+ // Use context locale if Next.js i18n is configured, otherwise use language defined in package.json
49
+ props.locale = context.locale ?? pkg.config.language;
50
+
51
+ // Fetch layout data, passing on req/res for SSR
52
+ props.layoutData = await this.layoutService.fetchLayoutData(
53
+ path,
54
+ props.locale,
55
+ // eslint-disable-next-line prettier/prettier
56
+ isServerSidePropsContext(context) ? (context as GetServerSidePropsContext).req : undefined,
57
+ isServerSidePropsContext(context) ? (context as GetServerSidePropsContext).res : undefined
58
+ );
59
+
60
+ if (!props.layoutData.sitecore.route) {
61
+ // A missing route value signifies an invalid path, so set notFound.
62
+ // Our page routes will return this in getStatic/ServerSideProps,
63
+ // which will trigger our custom 404 page with proper 404 status code.
64
+ // You could perform additional logging here to track these if desired.
65
+ props.notFound = true;
66
+ }
67
+
68
+ // Fetch dictionary data
69
+ props.dictionary = await this.dictionaryService.fetchDictionaryData(props.locale);
70
+
71
+ return props;
72
+ }
73
+ }
74
+
75
+ export const normalModePlugin = new NormalModePlugin();
@@ -0,0 +1,27 @@
1
+ import { editingDataService } from '@sitecore-jss/sitecore-jss-nextjs';
2
+ import { SitecorePageProps } from 'lib/page-props';
3
+ import { GetServerSidePropsContext, GetStaticPropsContext } from 'next';
4
+ import { Plugin } from '..';
5
+
6
+ class PreviewModePlugin implements Plugin {
7
+ order = 0;
8
+
9
+ async exec(props: SitecorePageProps, context: GetServerSidePropsContext | GetStaticPropsContext) {
10
+ if (!context.preview) return props;
11
+
12
+ // If we're in preview (editing) mode, use data already sent along with the editing request
13
+ const data = await editingDataService.getEditingData(context.previewData);
14
+ if (!data) {
15
+ throw new Error(
16
+ `Unable to get editing data for preview ${JSON.stringify(context.previewData)}`
17
+ );
18
+ }
19
+ props.locale = data.language;
20
+ props.layoutData = data.layoutData;
21
+ props.dictionary = data.dictionary;
22
+
23
+ return props;
24
+ }
25
+ }
26
+
27
+ export const previewModePlugin = new PreviewModePlugin();
@@ -0,0 +1,16 @@
1
+ import {
2
+ DictionaryPhrases,
3
+ ComponentPropsCollection,
4
+ LayoutServiceData,
5
+ } from '@sitecore-jss/sitecore-jss-nextjs';
6
+
7
+ /**
8
+ * Sitecore page props
9
+ */
10
+ export type SitecorePageProps = {
11
+ locale: string;
12
+ dictionary: DictionaryPhrases;
13
+ componentProps: ComponentPropsCollection;
14
+ notFound: boolean;
15
+ layoutData: LayoutServiceData;
16
+ };
@@ -0,0 +1,25 @@
1
+ import { GetStaticPathsContext } from 'next';
2
+ import { StaticPath } from '@sitecore-jss/sitecore-jss-nextjs';
3
+ import * as plugins from 'temp/sitemap-fetcher-plugins';
4
+
5
+ export interface SitemapFetcherPlugin {
6
+ /**
7
+ * A function which will be called during page props generation
8
+ */
9
+ exec(context?: GetStaticPathsContext): Promise<StaticPath[]>;
10
+ }
11
+
12
+ export class SitecoreSitemapFetcher {
13
+ /**
14
+ * Generates SitecoreSitemap for given mode (Export / Disconnected Export / SSG)
15
+ * @param {GetStaticPathsContext} context
16
+ */
17
+ async fetch(context?: GetStaticPathsContext): Promise<StaticPath[]> {
18
+ const pluginsList = Object.values(plugins) as SitemapFetcherPlugin[];
19
+ const pluginsResults = await Promise.all(pluginsList.map((plugin) => plugin.exec(context)));
20
+ const results = pluginsResults.reduce((acc, cur) => [...acc, ...cur], []);
21
+ return results;
22
+ }
23
+ }
24
+
25
+ export const sitemapFetcher = new SitecoreSitemapFetcher();
@@ -0,0 +1,36 @@
1
+ import { GraphQLSitemapService } from '@sitecore-jss/sitecore-jss-nextjs';
2
+ import config from 'temp/config';
3
+ import { SitemapFetcherPlugin } from '..';
4
+ import { GetStaticPathsContext } from 'next';
5
+ import pkg from '../../../../package.json';
6
+ import { StaticPath } from '@sitecore-jss/sitecore-jss-nextjs';
7
+
8
+ class GraphqlSitemapServicePlugin implements SitemapFetcherPlugin {
9
+ _graphqlSitemapService: GraphQLSitemapService;
10
+
11
+ constructor() {
12
+ this._graphqlSitemapService = new GraphQLSitemapService({
13
+ endpoint: config.graphQLEndpoint,
14
+ apiKey: config.sitecoreApiKey,
15
+ siteName: config.jssAppName,
16
+ /*
17
+ The Sitemap Service needs a root item ID in order to fetch the list of pages for the current
18
+ app. If your Sitecore instance only has 1 JSS App, you can specify the root item ID here;
19
+ otherwise, the service will attempt to figure out the root item for the current JSS App using GraphQL and app name.
20
+ rootItemId: '{GUID}'
21
+ */
22
+ });
23
+ }
24
+
25
+ async exec(context?: GetStaticPathsContext): Promise<StaticPath[]> {
26
+ if (process.env.EXPORT_MODE) {
27
+ // Disconnected Export mode
28
+ if (process.env.JSS_MODE !== 'disconnected') {
29
+ return this._graphqlSitemapService.fetchExportSitemap(pkg.config.language);
30
+ }
31
+ }
32
+ return this._graphqlSitemapService.fetchSSGSitemap(context?.locales || []);
33
+ }
34
+ }
35
+
36
+ export const graphqlSitemapServicePlugin = new GraphqlSitemapServicePlugin();
@@ -0,0 +1,5 @@
1
+ import NotFound from 'src/NotFound';
2
+
3
+ const Custom404 = (): JSX.Element => <NotFound />;
4
+
5
+ export default Custom404;
@@ -0,0 +1,91 @@
1
+ import { useEffect } from 'react';
2
+ <% if (prerender === 'SSG') { -%>
3
+ import { GetStaticPaths, GetStaticProps } from 'next';
4
+ <% } else if (prerender === 'SSR') { -%>
5
+ import { GetServerSideProps } from 'next';
6
+ <% } -%>
7
+ import NotFound from 'src/NotFound';
8
+ import Layout from 'src/Layout';
9
+ import {
10
+ SitecoreContext,
11
+ ComponentPropsContext,
12
+ handleEditorFastRefresh,
13
+ } from '@sitecore-jss/sitecore-jss-nextjs';
14
+ import { SitecorePageProps } from 'lib/page-props';
15
+ import { sitecorePagePropsFactory } from 'lib/page-props-factory';
16
+ import { componentFactory } from 'temp/componentFactory';
17
+ <% if (prerender === 'SSG') { -%>
18
+ import { sitemapFetcher } from 'lib/sitemap-fetcher';
19
+ <% } -%>
20
+
21
+ const SitecorePage = ({ notFound, componentProps, layoutData }: SitecorePageProps): JSX.Element => {
22
+ useEffect(() => {
23
+ // Since Sitecore editors do not support Fast Refresh, need to refresh EE chromes after Fast Refresh finished
24
+ handleEditorFastRefresh();
25
+ }, []);
26
+
27
+ if (notFound || !layoutData.sitecore.route) {
28
+ // Shouldn't hit this (as long as 'notFound' is being returned below), but just to be safe
29
+ return <NotFound />;
30
+ }
31
+
32
+ return (
33
+ <ComponentPropsContext value={componentProps}>
34
+ <SitecoreContext componentFactory={componentFactory} layoutData={layoutData}>
35
+ <Layout />
36
+ </SitecoreContext>
37
+ </ComponentPropsContext>
38
+ );
39
+ };
40
+
41
+ <% if (prerender === 'SSG') { -%>
42
+ // This function gets called at build and export time to determine
43
+ // pages for SSG ("paths", as tokenized array).
44
+ export const getStaticPaths: GetStaticPaths = async (context) => {
45
+ // Fallback, along with revalidate in getStaticProps (below),
46
+ // enables Incremental Static Regeneration. This allows us to
47
+ // leave certain (or all) paths empty if desired and static pages
48
+ // will be generated on request (development mode in this example).
49
+ // Alternatively, the entire sitemap could be pre-rendered
50
+ // ahead of time (non-development mode in this example).
51
+ // See https://nextjs.org/docs/basic-features/data-fetching#incremental-static-regeneration
52
+
53
+ if (process.env.NODE_ENV !== 'development') {
54
+ // Note: Next.js runs export in production mode
55
+ const paths = await sitemapFetcher.fetch(context);
56
+
57
+ return {
58
+ paths,
59
+ fallback: process.env.EXPORT_MODE ? false : 'blocking',
60
+ };
61
+ }
62
+
63
+ return {
64
+ paths: [],
65
+ fallback: 'blocking',
66
+ };
67
+ };
68
+
69
+ // This function gets called at build time on server-side.
70
+ // It may be called again, on a serverless function, if
71
+ // revalidation (or fallback) is enabled and a new request comes in.
72
+ export const getStaticProps: GetStaticProps = async (context) => {
73
+ <% } else if (prerender === 'SSR') { -%>
74
+ // This function gets called at request time on server-side.
75
+ export const getServerSideProps: GetServerSideProps = async (context) => {
76
+ <% } -%>
77
+ const props = await sitecorePagePropsFactory.create(context);
78
+
79
+ return {
80
+ props,
81
+ <% if (prerender === 'SSG') { -%>
82
+ // Next.js will attempt to re-generate the page:
83
+ // - When a request comes in
84
+ // - At most once every 5 seconds
85
+ revalidate: 5, // In seconds
86
+ <% } -%>
87
+ notFound: props.notFound, // Returns custom 404 page with a status code of 404 when true
88
+ };
89
+ };
90
+
91
+ export default SitecorePage;
@@ -0,0 +1,19 @@
1
+ import type { AppProps } from 'next/app';
2
+ import { I18nProvider } from 'next-localization';
3
+
4
+ import 'assets/app.css';
5
+
6
+ function App({ Component, pageProps }: AppProps): JSX.Element {
7
+ const { dictionary, ...rest } = pageProps;
8
+
9
+ return (
10
+ // Use the next-localization (w/ rosetta) library to provide our translation dictionary to the app.
11
+ // Note Next.js does not (currently) provide anything for translation, only i18n routing.
12
+ // If your app is not multilingual, next-localization and references to it can be removed.
13
+ <I18nProvider lngDict={dictionary} locale={pageProps.locale}>
14
+ <Component {...rest} />
15
+ </I18nProvider>
16
+ );
17
+ }
18
+
19
+ export default App;