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,50 @@
1
+ import { Text, Field, withDatasourceCheck } from '@sitecore-jss/sitecore-jss-nextjs';
2
+ import Link from 'next/link';
3
+ import { useI18n } from 'next-localization';
4
+ import StyleguideSpecimen from './Styleguide-Specimen';
5
+ import { ComponentWithContextProps } from 'lib/component-props';
6
+ import { StyleguideSpecimenFields } from 'lib/component-props/styleguide';
7
+
8
+ type StyleguideMultilingualProps = ComponentWithContextProps &
9
+ StyleguideSpecimenFields & {
10
+ fields: {
11
+ sample: Field<string>;
12
+ };
13
+ };
14
+
15
+ /**
16
+ * Demonstrates using the dictionary functionality and defining route data in
17
+ * multiple languages.
18
+ */
19
+ const StyleguideMultilingual = (props: StyleguideMultilingualProps): JSX.Element => {
20
+ const { t, locale } = useI18n();
21
+
22
+ return (
23
+ <StyleguideSpecimen {...props} e2eId="styleguide-multilingual">
24
+ <Text field={props.fields.sample} encode={false} tag="p" />
25
+
26
+ <p>
27
+ This is a static dictionary entry from <code>/data/dictionary</code>
28
+ :&nbsp;
29
+ {t('styleguide-sample')}
30
+ </p>
31
+
32
+ <p>
33
+ {/* In case if href already includes locale: https://nextjs.org/docs/advanced-features/i18n-routing#transition-between-locales */}
34
+ <Link href="/en/styleguide" locale={false}>
35
+ <a>Show in English</a>
36
+ </Link>
37
+ <br />
38
+ <% if (language) { -%>
39
+ <Link href="/styleguide" locale="<%- language %>">
40
+ <a>Show in <%- language %></a>
41
+ </Link>
42
+ <% } -%>
43
+ </p>
44
+
45
+ <p>The current language is: {locale()}</p>
46
+ </StyleguideSpecimen>
47
+ );
48
+ };
49
+
50
+ export default withDatasourceCheck()<StyleguideMultilingualProps>(StyleguideMultilingual);
@@ -0,0 +1,37 @@
1
+ import Link from 'next/link';
2
+ import { Text, Field, useSitecoreContext } from '@sitecore-jss/sitecore-jss-nextjs';
3
+ import StyleguideSpecimen from './Styleguide-Specimen';
4
+ import { ComponentProps } from 'lib/component-props';
5
+ import { StyleguideSpecimenFields } from 'lib/component-props/styleguide';
6
+
7
+ type StyleguideRouteFieldsProps = ComponentProps & StyleguideSpecimenFields;
8
+
9
+ type StyleguideRouteFields = {
10
+ pageTitle: Field<string>;
11
+ };
12
+
13
+ /**
14
+ * Demonstrates gaining access to route-level fields.
15
+ * This technique builds on the Styleguide-SitecoreContext technique,
16
+ * to also get the route level field data and make it editable.
17
+ */
18
+ const StyleguideRouteFields = (props: StyleguideRouteFieldsProps): JSX.Element => {
19
+ const value = useSitecoreContext();
20
+ const fields = value.sitecoreContext.route?.fields as StyleguideRouteFields;
21
+
22
+ return (
23
+ <StyleguideSpecimen {...props} e2eId="styleguide-route-fields">
24
+ <p>
25
+ Route level <code>pageTitle</code> field:{' '}
26
+ {value.sitecoreContext.route && <Text field={fields.pageTitle} />}
27
+ </p>
28
+ <p>
29
+ <Link href="/styleguide/custom-route-type">
30
+ <a>Sample of using a custom route type</a>
31
+ </Link>
32
+ </p>
33
+ </StyleguideSpecimen>
34
+ );
35
+ };
36
+
37
+ export default StyleguideRouteFields;
@@ -0,0 +1,22 @@
1
+ import { Field, Placeholder, Text, withDatasourceCheck } from '@sitecore-jss/sitecore-jss-nextjs';
2
+ import { ComponentProps } from 'lib/component-props';
3
+
4
+ type StyleguideSectionProps = ComponentProps & {
5
+ fields: {
6
+ heading: Field<string>;
7
+ };
8
+ };
9
+
10
+ /**
11
+ * Represents a category of styleguide specimens within the Styleguide-Layout.
12
+ * Usage examples are added to the `styleguide-section` placeholder that this
13
+ * exposes.
14
+ */
15
+ const StyleguideSection = (props: StyleguideSectionProps): JSX.Element => (
16
+ <div className="pt-3" id={`i${props.rendering.uid && props.rendering.uid.replace(/[{}]/g, '')}`}>
17
+ <Text className="border-bottom" field={props.fields.heading} tag="h3" />
18
+ <Placeholder name="<%- helper.getAppPrefix(appPrefix, appName) %>jss-styleguide-section" rendering={props.rendering} />
19
+ </div>
20
+ );
21
+
22
+ export default withDatasourceCheck()<StyleguideSectionProps>(StyleguideSection);
@@ -0,0 +1,25 @@
1
+ import { useSitecoreContext } from '@sitecore-jss/sitecore-jss-nextjs';
2
+ import StyleguideSpecimen from './Styleguide-Specimen';
3
+ import { ComponentProps } from 'lib/component-props';
4
+ import { StyleguideSpecimenFields } from 'lib/component-props/styleguide';
5
+
6
+ type StyleguideSitecoreContextProps = ComponentProps & StyleguideSpecimenFields;
7
+
8
+ /**
9
+ * Demonstrates gaining access to the route-level Sitecore Context from
10
+ * within other components.
11
+ */
12
+ const StyleguideSitecoreContext = (props: StyleguideSitecoreContextProps): JSX.Element => {
13
+ const { sitecoreContext } = useSitecoreContext();
14
+
15
+ return (
16
+ <StyleguideSpecimen {...props} e2eId="styleguide-sitecore-context">
17
+ <p>The current Sitecore Context is...</p>
18
+ <pre style={{ maxHeight: '400px', overflow: 'scroll' }}>
19
+ {JSON.stringify(sitecoreContext, null, 2)}
20
+ </pre>
21
+ </StyleguideSpecimen>
22
+ );
23
+ };
24
+
25
+ export default StyleguideSitecoreContext;
@@ -0,0 +1,41 @@
1
+ import { Text, RichText, withDatasourceCheck } from '@sitecore-jss/sitecore-jss-nextjs';
2
+ import { ComponentProps } from 'lib/component-props';
3
+ import { StyleguideSpecimenFields } from 'lib/component-props/styleguide';
4
+
5
+ type StyleguideSpecimenProps = ComponentProps &
6
+ StyleguideSpecimenFields & {
7
+ e2eId: string;
8
+ children: React.ReactNode;
9
+ };
10
+
11
+ /**
12
+ * Helper component that displays explanatory information and where to find the definitions
13
+ * of styleguide specimens.
14
+ */
15
+ const StyleguideSpecimen = ({
16
+ fields: { heading, description },
17
+ children,
18
+ rendering,
19
+ e2eId,
20
+ }: StyleguideSpecimenProps): JSX.Element => (
21
+ <div
22
+ className="pt-3"
23
+ id={`i${rendering.uid && rendering.uid.replace(/[{}]/g, '')}`}
24
+ data-e2e-id={e2eId}
25
+ >
26
+ <Text tag="h4" field={heading} />
27
+ <RichText field={description} />
28
+
29
+ <p>
30
+ <small>
31
+ Implementation: <code>/src/components/**/{rendering.componentName}.tsx</code>
32
+ <br />
33
+ Definition:{' '}
34
+ <code>/sitecore/definitions/components/**/{rendering.componentName}.sitecore.js</code>
35
+ </small>
36
+ </p>
37
+ <div className="border p-2">{children}</div>
38
+ </div>
39
+ );
40
+
41
+ export default withDatasourceCheck()<StyleguideSpecimenProps>(StyleguideSpecimen);
@@ -0,0 +1,341 @@
1
+ import React, { RefObject } from 'react';
2
+ import {
3
+ withSitecoreContext,
4
+ trackingApi,
5
+ TrackingRequestOptions,
6
+ } from '@sitecore-jss/sitecore-jss-nextjs';
7
+ import { dataFetcher } from 'lib/data-fetcher';
8
+ import config from 'temp/config';
9
+ import StyleguideSpecimen from './Styleguide-Specimen';
10
+ import { ComponentWithContextProps } from 'lib/component-props';
11
+ import { StyleguideSpecimenFields } from 'lib/component-props/styleguide';
12
+
13
+ /* eslint-disable no-alert,no-undef */
14
+
15
+ type StyleguideTrackingProps = ComponentWithContextProps & StyleguideSpecimenFields;
16
+
17
+ /**
18
+ * Demonstrates analytics tracking patterns (xDB)
19
+ */
20
+ class StyleguideTracking extends React.Component<StyleguideTrackingProps> {
21
+ private event: RefObject<HTMLInputElement>;
22
+ private goal: RefObject<HTMLInputElement>;
23
+ private outcomeName: RefObject<HTMLInputElement>;
24
+ private outcomeValue: RefObject<HTMLInputElement>;
25
+ private campaign: RefObject<HTMLInputElement>;
26
+ private pageId: RefObject<HTMLInputElement>;
27
+ private pageUrl: RefObject<HTMLInputElement>;
28
+
29
+ private trackingApiOptions: TrackingRequestOptions;
30
+
31
+ constructor(props: StyleguideTrackingProps) {
32
+ super(props);
33
+
34
+ this.event = React.createRef();
35
+ this.goal = React.createRef();
36
+ this.outcomeName = React.createRef();
37
+ this.outcomeValue = React.createRef();
38
+ this.campaign = React.createRef();
39
+ this.pageId = React.createRef();
40
+ this.pageUrl = React.createRef();
41
+
42
+ this.trackingApiOptions = {
43
+ host: config.sitecoreApiHost,
44
+ querystringParams: {
45
+ sc_apikey: config.sitecoreApiKey,
46
+ },
47
+ fetcher: dataFetcher,
48
+ };
49
+ }
50
+
51
+ submitEvent() {
52
+ if (!this.event.current) return;
53
+
54
+ trackingApi
55
+ .trackEvent([{ eventId: this.event.current.value }], this.trackingApiOptions)
56
+ .then(() => alert('Page event pushed'))
57
+ .catch((error) => alert(error));
58
+ }
59
+
60
+ submitGoal() {
61
+ if (!this.goal.current) return;
62
+
63
+ trackingApi
64
+ .trackEvent([{ goalId: this.goal.current.value }], this.trackingApiOptions)
65
+ .then(() => alert('Goal pushed'))
66
+ .catch((error) => alert(error));
67
+ }
68
+
69
+ submitOutcome() {
70
+ if (
71
+ !this.pageUrl.current ||
72
+ !this.pageId.current ||
73
+ !this.outcomeName.current ||
74
+ !this.outcomeValue.current
75
+ ) {
76
+ return;
77
+ }
78
+
79
+ trackingApi
80
+ .trackEvent(
81
+ [
82
+ {
83
+ url: this.pageUrl.current.value,
84
+ pageId: this.pageId.current.value,
85
+ outcomeId: this.outcomeName.current.value,
86
+ currencyCode: 'USD',
87
+ monetaryValue: this.outcomeValue.current.value,
88
+ },
89
+ ],
90
+ this.trackingApiOptions
91
+ )
92
+ .then(() => alert('Outcome pushed'))
93
+ .catch((error) => alert(error));
94
+ }
95
+
96
+ triggerCampaign() {
97
+ if (!this.campaign.current) return;
98
+
99
+ trackingApi
100
+ .trackEvent([{ campaignId: this.campaign.current.value }], this.trackingApiOptions)
101
+ .then(() => alert('Campaign set'))
102
+ .catch((error) => alert(error));
103
+ }
104
+
105
+ submitPageView() {
106
+ if (!this.pageId.current || !this.pageUrl.current) return;
107
+
108
+ trackingApi
109
+ .trackEvent(
110
+ [
111
+ {
112
+ pageId: this.pageId.current.value,
113
+ url: this.pageUrl.current.value,
114
+ },
115
+ ],
116
+ this.trackingApiOptions
117
+ )
118
+ .then(() => alert('Page view pushed'))
119
+ .catch((error) => alert(error));
120
+ }
121
+
122
+ abandonSession() {
123
+ const abandonOptions = {
124
+ action: 'flush',
125
+ ...this.trackingApiOptions,
126
+ };
127
+
128
+ trackingApi
129
+ .trackEvent([], abandonOptions)
130
+ .then(() => alert('Interaction has been terminated and its data pushed to xConnect.'))
131
+ .catch((error) => alert(error));
132
+ }
133
+
134
+ submitBatching() {
135
+ trackingApi
136
+ .trackEvent(
137
+ [
138
+ { eventId: 'Download' },
139
+ { goalId: 'Instant Demo' },
140
+ { outcomeId: 'Opportunity' },
141
+ {
142
+ pageId: '{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}',
143
+ url: '/arbitrary/url/you/own',
144
+ },
145
+ // this goal will be added to the new page/route ID set above, not the current route
146
+ { goalId: 'Register' },
147
+ ],
148
+ this.trackingApiOptions
149
+ )
150
+ .then(() => alert('Batch of events pushed'))
151
+ .catch((error) => alert(error));
152
+ }
153
+
154
+ render() {
155
+ const disconnectedMode = this.props.sitecoreContext.itemId === 'available-in-connected-mode';
156
+
157
+ return (
158
+ <StyleguideSpecimen {...this.props} e2eId="styleguide-tracking">
159
+ {disconnectedMode && (
160
+ <p>The tracking API is only available in connected, integrated, or headless modes.</p>
161
+ )}
162
+ {!disconnectedMode && (
163
+ <div>
164
+ <p className="alert alert-warning">
165
+ Note: The JSS tracker API is disabled by default. Consult the{' '}
166
+ <a href="https://jss.sitecore.com/docs/fundamentals/services/tracking">
167
+ tracking documentation
168
+ </a>{' '}
169
+ to enable it.
170
+ </p>
171
+ <div className="row">
172
+ <fieldset className="form-group col-sm">
173
+ <legend>Event</legend>
174
+ <p>
175
+ Events are defined in <code>/sitecore/system/Settings/Analytics/Page Events</code>
176
+ </p>
177
+ <label htmlFor="event">Event GUID or Name</label>
178
+ <input type="text" id="event" className="form-control" ref={this.event} />
179
+ <button
180
+ type="button"
181
+ className="btn btn-primary mt-3"
182
+ onClick={this.submitEvent.bind(this)}
183
+ >
184
+ Submit
185
+ </button>
186
+ </fieldset>
187
+
188
+ <fieldset className="form-group col-sm">
189
+ <legend>Goal</legend>
190
+ <p>
191
+ Goals are defined in <code>/sitecore/system/Marketing Control Panel/Goals</code>
192
+ </p>
193
+ <label htmlFor="goal">Goal GUID or Name</label>
194
+ <input
195
+ type="text"
196
+ className="form-control"
197
+ id="goal"
198
+ ref={this.goal}
199
+ placeholder="i.e. Register"
200
+ />
201
+ <button
202
+ type="button"
203
+ className="btn btn-primary mt-3"
204
+ onClick={this.submitGoal.bind(this)}
205
+ >
206
+ Submit
207
+ </button>
208
+ </fieldset>
209
+ </div>
210
+ <div className="row">
211
+ <fieldset className="form-group col-sm">
212
+ <legend>Outcome</legend>
213
+ <p>
214
+ Outcomes are defined in{' '}
215
+ <code>/sitecore/system/Marketing Control Panel/Outcomes</code>
216
+ </p>
217
+ <label htmlFor="outcomeName">Outcome GUID or Name</label>
218
+ <input
219
+ type="text"
220
+ className="form-control"
221
+ id="outcomeName"
222
+ ref={this.outcomeName}
223
+ placeholder="i.e. Marketing Lead"
224
+ />
225
+ <br />
226
+ <label htmlFor="outcomeValue">Monetary Value (optional)</label>
227
+ <input
228
+ type="number"
229
+ className="form-control"
230
+ id="outcomeValue"
231
+ ref={this.outcomeValue}
232
+ placeholder="i.e. 1337.00"
233
+ />
234
+ <button
235
+ type="button"
236
+ className="btn btn-primary mt-3"
237
+ onClick={this.submitOutcome.bind(this)}
238
+ >
239
+ Submit
240
+ </button>
241
+ </fieldset>
242
+
243
+ <fieldset className="form-group col-sm">
244
+ <legend>Campaign</legend>
245
+ <p>
246
+ Campaigns are defined in{' '}
247
+ <code>/sitecore/system/Marketing Control Panel/Campaigns</code>
248
+ </p>
249
+ <label htmlFor="campaign">Campaign GUID or Name</label>
250
+ <input type="text" className="form-control" id="campaign" ref={this.campaign} />
251
+ <button
252
+ type="button"
253
+ className="btn btn-primary mt-3"
254
+ onClick={this.triggerCampaign.bind(this)}
255
+ >
256
+ Submit
257
+ </button>
258
+ </fieldset>
259
+ </div>
260
+ <div className="row">
261
+ <fieldset className="form-group col-sm">
262
+ <legend>Page View</legend>
263
+ <p>
264
+ Track arbitrary page views for custom routing or offline use. Note that Layout
265
+ Service tracks page views by default unless <code>tracking=false</code> is passed
266
+ in its query string.
267
+ </p>
268
+ <label htmlFor="pageId">Page Item GUID</label>
269
+ <input
270
+ type="text"
271
+ className="form-control"
272
+ id="pageId"
273
+ ref={this.pageId}
274
+ placeholder="i.e. {11111111-1111-1111-1111-111111111111}"
275
+ />
276
+ <br />
277
+ <label htmlFor="pageUrl">Page URL</label>
278
+ <input
279
+ type="text"
280
+ className="form-control"
281
+ id="pageUrl"
282
+ ref={this.pageUrl}
283
+ placeholder="i.e. /foo/bar"
284
+ />
285
+ <button
286
+ type="button"
287
+ className="btn btn-primary mt-3"
288
+ onClick={this.submitPageView.bind(this)}
289
+ >
290
+ Submit
291
+ </button>
292
+ </fieldset>
293
+
294
+ <fieldset className="form-group col-sm">
295
+ <legend>Batching</legend>
296
+ <p>
297
+ The tracking API supports pushing a whole batch of events in a single request.
298
+ This can be useful for queuing strategies or offline PWA usage.
299
+ </p>
300
+ <button
301
+ type="button"
302
+ className="btn btn-primary"
303
+ onClick={this.submitBatching.bind(this)}
304
+ >
305
+ Submit Batch of Events
306
+ </button>
307
+ </fieldset>
308
+ </div>
309
+ <div className="row">
310
+ <fieldset className="form-group col-sm">
311
+ <legend>Interaction Control</legend>
312
+ <p>
313
+ Tracking data is not pushed into the xConnect service until your session ends on
314
+ the Sitecore server. Click this button to instantly end your session and flush the
315
+ data - great for debugging and testing.
316
+ </p>
317
+ <p className="alert alert-warning">
318
+ Note: By default <em>anonymous</em> contacts will not be shown in Experience
319
+ Profile. If your interactions are not showing up in Experience Profile, you may
320
+ need to{' '}
321
+ <a href="https://doc.sitecore.net/developers/xp/xconnect/xconnect-search-indexer/enable-anonymous-contact-indexing.html">
322
+ enable anonymous contact indexing.
323
+ </a>
324
+ </p>
325
+ <button
326
+ type="button"
327
+ className="btn btn-primary"
328
+ onClick={this.abandonSession.bind(this)}
329
+ >
330
+ End Interaction
331
+ </button>
332
+ </fieldset>
333
+ </div>
334
+ </div>
335
+ )}
336
+ </StyleguideSpecimen>
337
+ );
338
+ }
339
+ }
340
+
341
+ export default withSitecoreContext()(StyleguideTracking);
@@ -0,0 +1,11 @@
1
+ import { Field } from '@sitecore-jss/sitecore-jss-nextjs';
2
+
3
+ /**
4
+ * Shared styleguide specimen fields
5
+ */
6
+ export type StyleguideSpecimenFields = {
7
+ fields: {
8
+ description: Field<string>;
9
+ heading: Field<string>;
10
+ };
11
+ };
@@ -0,0 +1,43 @@
1
+ const { constants } = require('@sitecore-jss/sitecore-jss-nextjs');
2
+
3
+ const disconnectedServerUrl = `http://localhost:${process.env.PROXY_PORT || 3042}/`;
4
+ const isDisconnected = process.env.JSS_MODE === constants.JSS_MODE.DISCONNECTED;
5
+
6
+ const disconnectedPlugin = (nextConfig = {}) => {
7
+ if (!isDisconnected) {
8
+ return nextConfig;
9
+ }
10
+
11
+ return Object.assign({}, nextConfig, {
12
+ async rewrites() {
13
+ // When disconnected we proxy to the local faux layout service host, see scripts/disconnected-mode-server.js
14
+ return [
15
+ {
16
+ source: '/sitecore/:path*',
17
+ destination: `${disconnectedServerUrl}/sitecore/:path*`,
18
+ },
19
+ // media items
20
+ {
21
+ source: '/data/media/:path*',
22
+ destination: `${disconnectedServerUrl}/data/media/:path*`,
23
+ },
24
+ ];
25
+ },
26
+
27
+ webpack: (config, options) => {
28
+ // Prevent webpack-5 from throwing error for sitecore-import.json when app first starts
29
+ config.resolve.fallback = {
30
+ 'sitecore/manifest/sitecore-import.json': false
31
+ };
32
+
33
+ // Overload the Webpack config if it was already overloaded
34
+ if (typeof nextConfig.webpack === 'function') {
35
+ return nextConfig.webpack(config, options);
36
+ }
37
+
38
+ return config;
39
+ }
40
+ });
41
+ };
42
+
43
+ module.exports = disconnectedPlugin;
@@ -0,0 +1,10 @@
1
+ const styleguidePlugin = (nextConfig = {}) => {
2
+ return Object.assign({}, nextConfig, {
3
+ i18n: {
4
+ ...nextConfig.i18n,
5
+ locales: ['en'<%- language ? `, '${language}'` : ''%>],
6
+ },
7
+ });
8
+ };
9
+
10
+ module.exports = styleguidePlugin;
@@ -0,0 +1,46 @@
1
+ import { DisconnectedSitemapService } from '@sitecore-jss/sitecore-jss-nextjs';
2
+ import { ManifestInstance } from '@sitecore-jss/sitecore-jss-dev-tools';
3
+ import { SitemapFetcherPlugin } from '..';
4
+
5
+ class DisconnectedSitemapServicePlugin implements SitemapFetcherPlugin {
6
+ _disconnectedSitemapService: DisconnectedSitemapService;
7
+
8
+ constructor() {
9
+ this._disconnectedSitemapService = new DisconnectedSitemapService(
10
+ this.getManifest() as unknown as ManifestInstance
11
+ );
12
+ }
13
+
14
+ /**
15
+ * Get sitecore-import.json manifest
16
+ */
17
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
18
+ getManifest() {
19
+ if (process.env.JSS_MODE !== 'disconnected') return null;
20
+
21
+ try {
22
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
23
+ const manifest = require('sitecore/manifest/sitecore-import.json');
24
+
25
+ return manifest;
26
+ } catch (error) {
27
+ throw Error(
28
+ "[Disconnected Export] Please make sure you've started the disconnected proxy `npm run start:disconnected-proxy`"
29
+ );
30
+ }
31
+ }
32
+
33
+ async exec() {
34
+ // If we are in Export mode
35
+ if (process.env.EXPORT_MODE) {
36
+ // Disconnected Export mode
37
+ if (process.env.JSS_MODE === 'disconnected') {
38
+ return this._disconnectedSitemapService.fetchExportSitemap();
39
+ }
40
+ }
41
+
42
+ return [];
43
+ }
44
+ }
45
+
46
+ export const disconnectedSitemapServicePlugin = new DisconnectedSitemapServicePlugin();
@@ -0,0 +1,33 @@
1
+ import type { AppProps } from 'next/app';
2
+ import Router from 'next/router';
3
+ import { I18nProvider } from 'next-localization';
4
+ import NProgress from 'nprogress';
5
+
6
+ // Using bootstrap and nprogress are completely optional.
7
+ // bootstrap is used here to provide a clean layout for samples, without needing extra CSS in the sample app
8
+ // nprogress provides a loading indicator on page/route changes
9
+ // Remove these in package.json as well if removed here.
10
+ import 'bootstrap/dist/css/bootstrap.css';
11
+ import 'nprogress/nprogress.css';
12
+ import 'assets/app.css';
13
+
14
+ NProgress.configure({ showSpinner: false, trickleSpeed: 100 });
15
+
16
+ Router.events.on('routeChangeStart', () => NProgress.start());
17
+ Router.events.on('routeChangeComplete', () => NProgress.done());
18
+ Router.events.on('routeChangeError', () => NProgress.done());
19
+
20
+ function App({ Component, pageProps }: AppProps): JSX.Element {
21
+ const { dictionary, ...rest } = pageProps;
22
+
23
+ return (
24
+ // Use the next-localization (w/ rosetta) library to provide our translation dictionary to the app.
25
+ // Note Next.js does not (currently) provide anything for translation, only i18n routing.
26
+ // If your app is not multilingual, next-localization and references to it can be removed.
27
+ <I18nProvider lngDict={dictionary} locale={pageProps.locale}>
28
+ <Component {...rest} />
29
+ </I18nProvider>
30
+ );
31
+ }
32
+
33
+ export default App;