From 9aa7d801ba6133a2effe48a8381b27bb4a04901e Mon Sep 17 00:00:00 2001
From: Adam Brauer <400763+ambrauer@users.noreply.github.com>
Date: Tue, 7 Nov 2023 10:06:36 -0600
Subject: [PATCH] [Next.js] Introduce `nextjs-xmcloud` Initializer Template
(#1653)
* rename nextjs-personalize -> nextjs-xmcloud. move feaas and BYOC here.
* Move Sitecore Edge Platform / conext related items to nextjs-xmcloud
* Repurpose nextjs-personalize -> nextjs-xmcloud initializer "system" template (driven by prompt / --xmcloud CLI option)
* Moved skipping of site information fetch on XM Cloud to base package (GraphQLSiteInfoService)
* CHANGELOG update
* fix scaffold samples
* removed from sxa Layout.tsx
* fix for PR comment
(cherry picked from commit 19f5c22ac9ad857b7d401398672250e68bdfbcbe)
---
CHANGELOG.md | 7 +-
.../nextjs-styleguide-tracking/index.ts | 6 +-
.../index.ts | 9 +--
.../src/initializers/nextjs/index.ts | 71 ++++++++++++-------
.../src/initializers/nextjs/prompts.ts | 19 ++---
.../scripts/config/plugins/multisite.ts | 32 +++------
.../templates/nextjs-personalize/package.json | 5 --
.../src/templates/nextjs-sxa/src/Layout.tsx | 3 -
.../.env | 49 +++++++------
.../src/templates/nextjs-xmcloud/package.json | 7 ++
.../scripts/config/plugins/edge-platform.ts | 32 +++++++++
.../plugins/feaas.ts | 0
.../scaffold-component/plugins/byoc.ts | 0
.../plugins/next-steps-byoc.ts | 0
.../scripts/templates/byoc-component-src.ts | 0
.../src/Scripts.tsx | 3 +
.../src/byoc/index.client.tsx | 0
.../src/byoc/index.hybrid.ts | 0
.../src/byoc/index.ts | 0
.../src/components/CdpPageView.tsx | 0
.../lib/extract-path/plugins/personalize.ts | 0
.../src/lib/graphql-client-factory/create.ts | 32 +++++++++
.../src/lib/middleware/plugins/personalize.ts | 0
.../src/lib/next-config/plugins/feaas.js | 0
.../src/lib/next-config/plugins/monorepo.js | 30 ++++++++
.../plugins/feaas-themes.ts | 0
.../page-props-factory/plugins/personalize.ts | 0
.../src/lib/site-resolver/plugins/default.ts | 0
.../src/templates/nextjs/.env | 10 +--
.../nextjs/scripts/config/plugins/fallback.ts | 10 ---
.../nextjs/scripts/generate-config.ts | 2 -
.../src/templates/nextjs/src/Layout.tsx | 3 -
.../src/templates/nextjs/src/lib/config.ts | 2 -
.../src/lib/graphql-client-factory/create.ts | 11 +--
.../src/lib/next-config/plugins/monorepo.js | 9 ---
.../src/site/graphql-siteinfo-service.test.ts | 36 +++++++++-
.../src/site/graphql-siteinfo-service.ts | 4 ++
scripts/samples.json | 4 +-
38 files changed, 253 insertions(+), 143 deletions(-)
rename packages/create-sitecore-jss/src/initializers/{nextjs-personalize => nextjs-xmcloud}/index.ts (73%)
delete mode 100644 packages/create-sitecore-jss/src/templates/nextjs-personalize/package.json
rename packages/create-sitecore-jss/src/templates/{nextjs-personalize => nextjs-xmcloud}/.env (78%)
create mode 100644 packages/create-sitecore-jss/src/templates/nextjs-xmcloud/package.json
create mode 100644 packages/create-sitecore-jss/src/templates/nextjs-xmcloud/scripts/config/plugins/edge-platform.ts
rename packages/create-sitecore-jss/src/templates/{nextjs => nextjs-xmcloud}/scripts/generate-component-builder/plugins/feaas.ts (100%)
rename packages/create-sitecore-jss/src/templates/{nextjs => nextjs-xmcloud}/scripts/scaffold-component/plugins/byoc.ts (100%)
rename packages/create-sitecore-jss/src/templates/{nextjs => nextjs-xmcloud}/scripts/scaffold-component/plugins/next-steps-byoc.ts (100%)
rename packages/create-sitecore-jss/src/templates/{nextjs => nextjs-xmcloud}/scripts/templates/byoc-component-src.ts (100%)
rename packages/create-sitecore-jss/src/templates/{nextjs-personalize => nextjs-xmcloud}/src/Scripts.tsx (52%)
rename packages/create-sitecore-jss/src/templates/{nextjs => nextjs-xmcloud}/src/byoc/index.client.tsx (100%)
rename packages/create-sitecore-jss/src/templates/{nextjs => nextjs-xmcloud}/src/byoc/index.hybrid.ts (100%)
rename packages/create-sitecore-jss/src/templates/{nextjs => nextjs-xmcloud}/src/byoc/index.ts (100%)
rename packages/create-sitecore-jss/src/templates/{nextjs-personalize => nextjs-xmcloud}/src/components/CdpPageView.tsx (100%)
rename packages/create-sitecore-jss/src/templates/{nextjs-personalize => nextjs-xmcloud}/src/lib/extract-path/plugins/personalize.ts (100%)
create mode 100644 packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/graphql-client-factory/create.ts
rename packages/create-sitecore-jss/src/templates/{nextjs-personalize => nextjs-xmcloud}/src/lib/middleware/plugins/personalize.ts (100%)
rename packages/create-sitecore-jss/src/templates/{nextjs => nextjs-xmcloud}/src/lib/next-config/plugins/feaas.js (100%)
create mode 100644 packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/next-config/plugins/monorepo.js
rename packages/create-sitecore-jss/src/templates/{nextjs => nextjs-xmcloud}/src/lib/page-props-factory/plugins/feaas-themes.ts (100%)
rename packages/create-sitecore-jss/src/templates/{nextjs-personalize => nextjs-xmcloud}/src/lib/page-props-factory/plugins/personalize.ts (100%)
rename packages/create-sitecore-jss/src/templates/{nextjs-personalize => nextjs-xmcloud}/src/lib/site-resolver/plugins/default.ts (100%)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ed240dbd25..b2d098f41d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,7 @@ Our versioning strategy is as follows:
* `[sitecore-jss-nextjs]` (Vercel/Sitecore) Deployment Protection Bypass support for editing integration. ([#1634](https://github.com/Sitecore/jss/pull/1634))
* `[sitecore-jss]` `[templates/nextjs]` Load environment-specific FEAAS theme stylesheets based on Sitecore Edge Platform URL ([#1645](https://github.com/Sitecore/jss/pull/1645))
* `[sitecore-jss-nextjs]` The _GraphQLRequestClient_ import from _@sitecore-jss/sitecore-jss-nextjs_ is deprecated, use import from _@sitecore-jss/sitecore-jss-nextjs/graphql_ submodule instead ([#1650](https://github.com/Sitecore/jss/pull/1650) [#1648](https://github.com/Sitecore/jss/pull/1648))
+* `[create-sitecore-jss]` Introduced `nextjs-xmcloud` initializer template. This will include all base XM Cloud features, including Personalize, FEaaS, BYOC, Sitecore Edge Platform and Context support. ([#1653](https://github.com/Sitecore/jss/pull/1653))
### 🐛 Bug Fixes
@@ -32,7 +33,11 @@ Our versioning strategy is as follows:
* `[sitecore-jss-nextjs]` Fix issue when redirects works each every other times. ([#1629](https://github.com/Sitecore/jss/pull/1629))
* `[templates/nextjs]` Fix custom headers. Now in cors-header plugin extends custom headers from next.config.js file. ([#1637](https://github.com/Sitecore/jss/pull/1637))
* `[sitecore-jss-react]` Fix PlaceholderCommon with using two and more dynamic placeholders. ([#1641](https://github.com/Sitecore/jss/pull/1641))
-* `[templates/nextjs-multisite]` Fix site info fetch errors (now skipped) on XM Cloud rendering/editing host builds. ([#1649](https://github.com/Sitecore/jss/pull/1649))
+* `[templates/nextjs-multisite]` Fix site info fetch errors (now skipped) on XM Cloud rendering/editing host builds. ([#1649](https://github.com/Sitecore/jss/pull/1649)), ([#1653](https://github.com/Sitecore/jss/pull/1653))
+
+### 🛠 Breaking Changes
+
+* `[create-sitecore-jss]` The `nextjs-personalize` initializer add-on template has been removed and is replaced by the `nextjs-xmcloud` initializer template. You can use the interactive prompts or the `--xmcloud` argument to include this template. ([#1653](https://github.com/Sitecore/jss/pull/1653))
## 21.5.0
diff --git a/packages/create-sitecore-jss/src/initializers/nextjs-styleguide-tracking/index.ts b/packages/create-sitecore-jss/src/initializers/nextjs-styleguide-tracking/index.ts
index 05a4163a18..81fe0dd663 100644
--- a/packages/create-sitecore-jss/src/initializers/nextjs-styleguide-tracking/index.ts
+++ b/packages/create-sitecore-jss/src/initializers/nextjs-styleguide-tracking/index.ts
@@ -35,10 +35,10 @@ export default class NextjsStyleguideInitializer implements Initializer {
}
if (
- args.templates.includes('nextjs-personalize') ||
- pkg.config?.templates?.includes('nextjs-personalize')
+ args.templates.includes('nextjs-xmcloud') ||
+ pkg.config?.templates?.includes('nextjs-xmcloud')
) {
- console.log(incompatibleAddonsMsg('nextjs-styleguide-tracking', 'nextjs-personalize'));
+ console.log(incompatibleAddonsMsg('nextjs-styleguide-tracking', 'nextjs-xmcloud'));
}
const response = {
diff --git a/packages/create-sitecore-jss/src/initializers/nextjs-personalize/index.ts b/packages/create-sitecore-jss/src/initializers/nextjs-xmcloud/index.ts
similarity index 73%
rename from packages/create-sitecore-jss/src/initializers/nextjs-personalize/index.ts
rename to packages/create-sitecore-jss/src/initializers/nextjs-xmcloud/index.ts
index 6439b7b8e1..16813e229a 100644
--- a/packages/create-sitecore-jss/src/initializers/nextjs-personalize/index.ts
+++ b/packages/create-sitecore-jss/src/initializers/nextjs-xmcloud/index.ts
@@ -8,7 +8,7 @@ import {
incompatibleAddonsMsg,
} from '../../common';
-export default class NextjsPersonalizeInitializer implements Initializer {
+export default class NextjsXMCloudInitializer implements Initializer {
get isBase(): boolean {
return false;
}
@@ -16,16 +16,13 @@ export default class NextjsPersonalizeInitializer implements Initializer {
async init(args: ClientAppArgs) {
const pkg = openPackageJson(`${args.destination}${sep}package.json`);
- // TODO: prompts for Personalize and argument types
- // const answers = await prompt(styleguidePrompts, args);
-
const mergedArgs = {
...args,
appName: args.appName || pkg?.config?.appName || DEFAULT_APPNAME,
appPrefix: args.appPrefix || pkg?.config?.prefix || false,
};
- const templatePath = path.resolve(__dirname, '../../templates/nextjs-personalize');
+ const templatePath = path.resolve(__dirname, '../../templates/nextjs-xmcloud');
await transform(templatePath, mergedArgs);
@@ -33,7 +30,7 @@ export default class NextjsPersonalizeInitializer implements Initializer {
args.templates.includes('nextjs-styleguide-tracking') ||
pkg.config?.templates?.includes('nextjs-styleguide-tracking')
) {
- console.log(incompatibleAddonsMsg('nextjs-personalize', 'nextjs-styleguide-tracking'));
+ console.log(incompatibleAddonsMsg('nextjs-xmcloud', 'nextjs-styleguide-tracking'));
}
const response = {
diff --git a/packages/create-sitecore-jss/src/initializers/nextjs/index.ts b/packages/create-sitecore-jss/src/initializers/nextjs/index.ts
index 843dec78a6..ad9fe98826 100644
--- a/packages/create-sitecore-jss/src/initializers/nextjs/index.ts
+++ b/packages/create-sitecore-jss/src/initializers/nextjs/index.ts
@@ -14,6 +14,36 @@ import { NextjsArgs } from './args';
inquirer.registerPrompt('nextjs-checkbox', NextjsCheckbox);
+enum PlatformCompatibility {
+ SXP,
+ XMC,
+ Both,
+}
+
+const addOnChoices = [
+ {
+ name: 'nextjs-styleguide - Includes example components and setup for working disconnected',
+ value: 'nextjs-styleguide',
+ platform: PlatformCompatibility.Both,
+ },
+ {
+ name: 'nextjs-styleguide-tracking - Includes example (Sitecore XP) tracking component',
+ value: 'nextjs-styleguide-tracking',
+ platform: PlatformCompatibility.SXP,
+ },
+ {
+ name: 'nextjs-sxa - Includes example components and setup for Headless SXA projects',
+ value: 'nextjs-sxa',
+ platform: PlatformCompatibility.Both,
+ },
+ {
+ name:
+ 'nextjs-multisite - Includes example setup for hosting multiple sites in a single NextJS application',
+ value: 'nextjs-multisite',
+ platform: PlatformCompatibility.Both,
+ },
+];
+
export default class NextjsInitializer implements Initializer {
get isBase(): boolean {
return true;
@@ -31,7 +61,12 @@ export default class NextjsInitializer implements Initializer {
removeDevDependencies(args.destination);
}
- let addInitializers: string[] = [];
+ const addInitializers: string[] = [];
+
+ if (answers.xmcloud && !args.templates.includes('nextjs-xmcloud')) {
+ // add the "system" nextjs-xmcloud template if needed
+ addInitializers.push('nextjs-xmcloud');
+ }
// don't prompt for add-on initializers if --yes or they've already specified
// multiple via --templates (assume they know what they're doing)
@@ -40,33 +75,15 @@ export default class NextjsInitializer implements Initializer {
type: 'nextjs-checkbox' as 'checkbox',
name: 'addInitializers',
message: 'Would you like to include any add-on initializers?',
- choices: [
- {
- name:
- 'nextjs-styleguide - Includes example components and setup for working disconnected',
- value: 'nextjs-styleguide',
- },
- {
- name: 'nextjs-styleguide-tracking - Includes example (Sitecore XP) tracking component',
- value: 'nextjs-styleguide-tracking',
- },
- {
- name: 'nextjs-sxa - Includes example components and setup for Headless SXA projects',
- value: 'nextjs-sxa',
- },
- {
- name:
- 'nextjs-personalize - Includes example setup for projects using XM Cloud Embedded Personalization',
- value: 'nextjs-personalize',
- },
- {
- name:
- 'nextjs-multisite - Includes example setup for hosting multiple sites in a single NextJS application',
- value: 'nextjs-multisite',
- },
- ],
+ choices: addOnChoices.filter((choice) => {
+ return (
+ choice.platform === PlatformCompatibility.Both ||
+ (answers.xmcloud && choice.platform === PlatformCompatibility.XMC) ||
+ (!answers.xmcloud && choice.platform === PlatformCompatibility.SXP)
+ );
+ }),
});
- addInitializers = addInitAnswer.addInitializers;
+ addInitializers.push(...addInitAnswer.addInitializers);
}
if (
diff --git a/packages/create-sitecore-jss/src/initializers/nextjs/prompts.ts b/packages/create-sitecore-jss/src/initializers/nextjs/prompts.ts
index e501ed1d91..1c04472e20 100644
--- a/packages/create-sitecore-jss/src/initializers/nextjs/prompts.ts
+++ b/packages/create-sitecore-jss/src/initializers/nextjs/prompts.ts
@@ -10,6 +10,7 @@ export enum Prerender {
export type NextjsAnswer = ClientAppAnswer & {
prerender: Prerender;
+ xmcloud: boolean;
};
const DEFAULT_PRERENDER = Prerender.SSG;
@@ -29,6 +30,15 @@ export const prompts: QuestionCollection = [
return !answers.prerender;
},
},
+ {
+ type: 'confirm',
+ name: 'xmcloud',
+ message: 'Are you building for Sitecore XM Cloud?',
+ default: false,
+ when: (answers: NextjsAnswer): boolean => {
+ return !answers.yes;
+ },
+ },
];
/**
@@ -45,15 +55,6 @@ export class NextjsCheckbox extends CheckboxPrompt {
return value === initializer && checked;
});
- const isPersonalizeSelected = isSelected('nextjs-personalize');
- const isTrackingSelected = isSelected('nextjs-styleguide-tracking');
-
- if (isPersonalizeSelected && isTrackingSelected) {
- this.onError({
- isValid: incompatibleAddonsMsg('nextjs-styleguide-tracking', 'nextjs-personalize'),
- });
- }
-
const isSxaSelected = isSelected('nextjs-sxa');
const isStyleguideSelected = isSelected('nextjs-styleguide');
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-multisite/scripts/config/plugins/multisite.ts b/packages/create-sitecore-jss/src/templates/nextjs-multisite/scripts/config/plugins/multisite.ts
index 754717a41f..56f7581f1c 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs-multisite/scripts/config/plugins/multisite.ts
+++ b/packages/create-sitecore-jss/src/templates/nextjs-multisite/scripts/config/plugins/multisite.ts
@@ -14,29 +14,15 @@ class MultisitePlugin implements ConfigPlugin {
async exec(config: JssConfig) {
let sites: SiteInfo[] = [];
-
- const endpoint = config.sitecoreEdgeContextId ? config.sitecoreEdgeUrl : config.graphQLEndpoint;
-
- if (!endpoint || process.env.SITECORE) {
- console.warn(
- chalk.yellow(
- `Skipping site information fetch (${
- !endpoint ? 'missing GraphQL endpoint' : 'building on XM Cloud'
- })`
- )
- );
- } else {
- console.log(`Fetching site information from ${endpoint}`);
-
- try {
- const siteInfoService = new GraphQLSiteInfoService({
- clientFactory: createGraphQLClientFactory(config),
- });
- sites = await siteInfoService.fetchSiteInfo();
- } catch (error) {
- console.error(chalk.red('Error fetching site information'));
- console.error(error);
- }
+ console.log('Fetching site information');
+ try {
+ const siteInfoService = new GraphQLSiteInfoService({
+ clientFactory: createGraphQLClientFactory(config),
+ });
+ sites = await siteInfoService.fetchSiteInfo();
+ } catch (error) {
+ console.error(chalk.red('Error fetching site information'));
+ console.error(error);
}
return Object.assign({}, config, {
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-personalize/package.json b/packages/create-sitecore-jss/src/templates/nextjs-personalize/package.json
deleted file mode 100644
index 6653194865..0000000000
--- a/packages/create-sitecore-jss/src/templates/nextjs-personalize/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "dependencies": {
- "@sitecore/engage": "^1.4.1"
- }
-}
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-sxa/src/Layout.tsx b/packages/create-sitecore-jss/src/templates/nextjs-sxa/src/Layout.tsx
index 17122e889d..3d4800e3d3 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs-sxa/src/Layout.tsx
+++ b/packages/create-sitecore-jss/src/templates/nextjs-sxa/src/Layout.tsx
@@ -11,8 +11,6 @@ import {
} from '@sitecore-jss/sitecore-jss-nextjs';
import { getPublicUrl } from '@sitecore-jss/sitecore-jss-nextjs/utils';
import Scripts from 'src/Scripts';
-// The bundle imports external (BYOC) components into the app and makes sure they are ready to be used.
-import BYOC from 'src/byoc';
// Prefix public assets with a public URL to enable compatibility with Sitecore Experience Editor.
// If you're not supporting the Experience Editor, you can remove this.
@@ -37,7 +35,6 @@ const Layout = ({ layoutData, headLinks }: LayoutProps): JSX.Element => {
return (
<>
-
{fields?.Title?.value?.toString() || 'Page'}
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-personalize/.env b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/.env
similarity index 78%
rename from packages/create-sitecore-jss/src/templates/nextjs-personalize/.env
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/.env
index a508d9edfb..45ccca7ccc 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs-personalize/.env
+++ b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/.env
@@ -1,20 +1,29 @@
-# Your Sitecore CDP API target (specific to your data center region)
-NEXT_PUBLIC_CDP_TARGET_URL=
-
-# Your Sitecore CDP client key
-NEXT_PUBLIC_CDP_CLIENT_KEY=
-
-# An optional Sitecore Personalize scope identifier.
-# This can be used to isolate personalization data when multiple XM Cloud Environments share a Personalize tenant.
-# This should match the PAGES_PERSONALIZE_SCOPE environment variable for your connected XM Cloud Environment.
-NEXT_PUBLIC_PERSONALIZE_SCOPE=
-
-# Your Sitecore CDP point(s) of sale
-# Can be provided as a single value (mypoint.com) or a multi-value JSON with locales ({"en":"en.mypoint.com","fr":"fr.mypoint.com"} etc)
-NEXT_PUBLIC_CDP_POINTOFSALE=
-
-# Timeout (ms) for Sitecore CDP requests to respond within. Default is 400.
-PERSONALIZE_MIDDLEWARE_CDP_TIMEOUT=
-
-# Timeout (ms) for Sitecore Experience Edge requests to respond within. Default is 400.
-PERSONALIZE_MIDDLEWARE_EDGE_TIMEOUT=
+
+# ========== Sitecore Edge Platform ===========
+
+# Your unified Sitecore Edge Context Id.
+# This will be used over any Sitecore Preview / Delivery Edge variables (above).
+SITECORE_EDGE_CONTEXT_ID=
+
+# ==============================================
+
+# Your Sitecore CDP API target (specific to your data center region)
+NEXT_PUBLIC_CDP_TARGET_URL=
+
+# Your Sitecore CDP client key
+NEXT_PUBLIC_CDP_CLIENT_KEY=
+
+# An optional Sitecore Personalize scope identifier.
+# This can be used to isolate personalization data when multiple XM Cloud Environments share a Personalize tenant.
+# This should match the PAGES_PERSONALIZE_SCOPE environment variable for your connected XM Cloud Environment.
+NEXT_PUBLIC_PERSONALIZE_SCOPE=
+
+# Your Sitecore CDP point(s) of sale
+# Can be provided as a single value (mypoint.com) or a multi-value JSON with locales ({"en":"en.mypoint.com","fr":"fr.mypoint.com"} etc)
+NEXT_PUBLIC_CDP_POINTOFSALE=
+
+# Timeout (ms) for Sitecore CDP requests to respond within. Default is 400.
+PERSONALIZE_MIDDLEWARE_CDP_TIMEOUT=
+
+# Timeout (ms) for Sitecore Experience Edge requests to respond within. Default is 400.
+PERSONALIZE_MIDDLEWARE_EDGE_TIMEOUT=
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/package.json b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/package.json
new file mode 100644
index 0000000000..33d06644d2
--- /dev/null
+++ b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/package.json
@@ -0,0 +1,7 @@
+{
+ "dependencies": {
+ "@sitecore/components": "~1.0.19",
+ "@sitecore/engage": "^1.4.1",
+ "@sitecore-feaas/clientside": "^0.4.12"
+ }
+}
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/scripts/config/plugins/edge-platform.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/scripts/config/plugins/edge-platform.ts
new file mode 100644
index 0000000000..d8779ff0bb
--- /dev/null
+++ b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/scripts/config/plugins/edge-platform.ts
@@ -0,0 +1,32 @@
+import 'dotenv/config';
+import chalk from 'chalk';
+import { constantCase } from 'constant-case';
+import { JssConfig } from 'lib/config';
+import { ConfigPlugin } from '..';
+
+/**
+ * This plugin will set config props used by the Sitecore Edge Platform.
+ */
+class EdgePlatformPlugin implements ConfigPlugin {
+ order = 2;
+
+ async exec(config: JssConfig) {
+ const sitecoreEdgeUrl = process.env[`${constantCase('sitecoreEdgeUrl')}`] || 'https://edge-platform.sitecorecloud.io';
+ const sitecoreEdgeContextId = process.env[`${constantCase('sitecoreEdgeContextId')}`];
+
+ if (config.sitecoreApiKey && sitecoreEdgeContextId) {
+ console.log(
+ chalk.yellow(
+ "You have configured both 'sitecoreApiKey' and 'sitecoreEdgeContextId' values. The 'sitecoreEdgeContextId' is used instead."
+ )
+ );
+ }
+
+ return Object.assign({}, config, {
+ sitecoreEdgeUrl,
+ sitecoreEdgeContextId,
+ });
+ }
+}
+
+export const edgePlatformPlugin = new EdgePlatformPlugin();
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/scripts/generate-component-builder/plugins/feaas.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/scripts/generate-component-builder/plugins/feaas.ts
similarity index 100%
rename from packages/create-sitecore-jss/src/templates/nextjs/scripts/generate-component-builder/plugins/feaas.ts
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/scripts/generate-component-builder/plugins/feaas.ts
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/scripts/scaffold-component/plugins/byoc.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/scripts/scaffold-component/plugins/byoc.ts
similarity index 100%
rename from packages/create-sitecore-jss/src/templates/nextjs/scripts/scaffold-component/plugins/byoc.ts
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/scripts/scaffold-component/plugins/byoc.ts
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/scripts/scaffold-component/plugins/next-steps-byoc.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/scripts/scaffold-component/plugins/next-steps-byoc.ts
similarity index 100%
rename from packages/create-sitecore-jss/src/templates/nextjs/scripts/scaffold-component/plugins/next-steps-byoc.ts
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/scripts/scaffold-component/plugins/next-steps-byoc.ts
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/scripts/templates/byoc-component-src.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/scripts/templates/byoc-component-src.ts
similarity index 100%
rename from packages/create-sitecore-jss/src/templates/nextjs/scripts/templates/byoc-component-src.ts
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/scripts/templates/byoc-component-src.ts
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-personalize/src/Scripts.tsx b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/Scripts.tsx
similarity index 52%
rename from packages/create-sitecore-jss/src/templates/nextjs-personalize/src/Scripts.tsx
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/Scripts.tsx
index 52ecf0b89a..8f7e0602a0 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs-personalize/src/Scripts.tsx
+++ b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/Scripts.tsx
@@ -1,8 +1,11 @@
+// The BYOC bundle imports external (BYOC) components into the app and makes sure they are ready to be used
+import BYOC from 'src/byoc';
import CdpPageView from 'components/CdpPageView';
const Scripts = (): JSX.Element => {
return (
<>
+
>
);
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/src/byoc/index.client.tsx b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/byoc/index.client.tsx
similarity index 100%
rename from packages/create-sitecore-jss/src/templates/nextjs/src/byoc/index.client.tsx
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/byoc/index.client.tsx
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/src/byoc/index.hybrid.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/byoc/index.hybrid.ts
similarity index 100%
rename from packages/create-sitecore-jss/src/templates/nextjs/src/byoc/index.hybrid.ts
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/byoc/index.hybrid.ts
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/src/byoc/index.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/byoc/index.ts
similarity index 100%
rename from packages/create-sitecore-jss/src/templates/nextjs/src/byoc/index.ts
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/byoc/index.ts
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-personalize/src/components/CdpPageView.tsx b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/components/CdpPageView.tsx
similarity index 100%
rename from packages/create-sitecore-jss/src/templates/nextjs-personalize/src/components/CdpPageView.tsx
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/components/CdpPageView.tsx
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-personalize/src/lib/extract-path/plugins/personalize.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/extract-path/plugins/personalize.ts
similarity index 100%
rename from packages/create-sitecore-jss/src/templates/nextjs-personalize/src/lib/extract-path/plugins/personalize.ts
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/extract-path/plugins/personalize.ts
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/graphql-client-factory/create.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/graphql-client-factory/create.ts
new file mode 100644
index 0000000000..bc76efc74f
--- /dev/null
+++ b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/graphql-client-factory/create.ts
@@ -0,0 +1,32 @@
+import {
+ GraphQLRequestClientFactoryConfig,
+ GraphQLRequestClient,
+ getEdgeProxyContentUrl
+} from '@sitecore-jss/sitecore-jss-nextjs/graphql';
+import { JssConfig } from 'lib/config';
+
+/**
+ * Creates a new GraphQLRequestClientFactory instance
+ * @param config jss config
+ * @returns GraphQLRequestClientFactory instance
+ */
+export const createGraphQLClientFactory = (config: JssConfig) => {
+ let clientConfig: GraphQLRequestClientFactoryConfig;
+
+ if (config.sitecoreEdgeContextId) {
+ clientConfig = {
+ endpoint: getEdgeProxyContentUrl(config.sitecoreEdgeContextId, config.sitecoreEdgeUrl),
+ };
+ } else if (config.graphQLEndpoint && config.sitecoreApiKey) {
+ clientConfig = {
+ endpoint: config.graphQLEndpoint,
+ apiKey: config.sitecoreApiKey,
+ };
+ } else {
+ throw new Error(
+ 'Please configure either your sitecoreEdgeContextId, or your graphQLEndpoint and sitecoreApiKey.'
+ );
+ }
+
+ return GraphQLRequestClient.createClientFactory(clientConfig);
+};
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-personalize/src/lib/middleware/plugins/personalize.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/middleware/plugins/personalize.ts
similarity index 100%
rename from packages/create-sitecore-jss/src/templates/nextjs-personalize/src/lib/middleware/plugins/personalize.ts
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/middleware/plugins/personalize.ts
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/src/lib/next-config/plugins/feaas.js b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/next-config/plugins/feaas.js
similarity index 100%
rename from packages/create-sitecore-jss/src/templates/nextjs/src/lib/next-config/plugins/feaas.js
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/next-config/plugins/feaas.js
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/next-config/plugins/monorepo.js b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/next-config/plugins/monorepo.js
new file mode 100644
index 0000000000..f1ce7c9a26
--- /dev/null
+++ b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/next-config/plugins/monorepo.js
@@ -0,0 +1,30 @@
+const path = require('path');
+const CWD = process.cwd();
+
+/**
+ * @param {import('next').NextConfig} nextConfig
+ */
+const monorepoPlugin = (nextConfig = {}) => {
+ return Object.assign({}, nextConfig, {
+ webpack: (config, options) => {
+ if (options.isServer) {
+ config.externals = ['react', 'vertx', ...config.externals];
+ }
+ // Monorepo support for @sitecore-feaas/clientside/react
+ config.resolve.alias['@sitecore-feaas/clientside/react'] = path.resolve(
+ CWD, options.isServer ?
+ './node_modules/@sitecore-feaas/clientside/dist/node/react.cjs' :
+ './node_modules/@sitecore-feaas/clientside/dist/browser/react.esm.js'
+ );
+
+ // Overload the Webpack config if it was already overloaded
+ if (typeof nextConfig.webpack === 'function') {
+ return nextConfig.webpack(config, options);
+ }
+
+ return config;
+ }
+ });
+};
+
+module.exports = monorepoPlugin;
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/src/lib/page-props-factory/plugins/feaas-themes.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/page-props-factory/plugins/feaas-themes.ts
similarity index 100%
rename from packages/create-sitecore-jss/src/templates/nextjs/src/lib/page-props-factory/plugins/feaas-themes.ts
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/page-props-factory/plugins/feaas-themes.ts
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-personalize/src/lib/page-props-factory/plugins/personalize.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/page-props-factory/plugins/personalize.ts
similarity index 100%
rename from packages/create-sitecore-jss/src/templates/nextjs-personalize/src/lib/page-props-factory/plugins/personalize.ts
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/page-props-factory/plugins/personalize.ts
diff --git a/packages/create-sitecore-jss/src/templates/nextjs-personalize/src/lib/site-resolver/plugins/default.ts b/packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/site-resolver/plugins/default.ts
similarity index 100%
rename from packages/create-sitecore-jss/src/templates/nextjs-personalize/src/lib/site-resolver/plugins/default.ts
rename to packages/create-sitecore-jss/src/templates/nextjs-xmcloud/src/lib/site-resolver/plugins/default.ts
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/.env b/packages/create-sitecore-jss/src/templates/nextjs/.env
index 3975c535d6..9f2db19a61 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs/.env
+++ b/packages/create-sitecore-jss/src/templates/nextjs/.env
@@ -17,15 +17,7 @@ PUBLIC_URL=http://localhost:3000
# We recommend an alphanumeric value of at least 16 characters.
JSS_EDITING_SECRET=
-# ===== Sitecore Edge Platform ======
-
-# Your unified Sitecore Edge Context Id.
-SITECORE_EDGE_CONTEXT_ID=
-
-# ================================
-
# ====== Sitecore Preview / Delivery Edge ======
-# (Sitecore Edge Proxy environment variables should be set empty, otherwise they will be prioritized and applied)
# Your Sitecore API key is needed to build the app. Typically, the API key is
# defined in `scjssconfig.json` (as `sitecore.apiKey`). This file may not exist
@@ -46,7 +38,7 @@ SITECORE_API_HOST=
# the resolved Sitecore API hostname + the `graphQLEndpointPath` defined in your `package.json`.
GRAPH_QL_ENDPOINT=
-# ================================
+# ==============================================
# Your Sitecore site name.
# Uses your `package.json` config `appName` if empty.
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/scripts/config/plugins/fallback.ts b/packages/create-sitecore-jss/src/templates/nextjs/scripts/config/plugins/fallback.ts
index ba3b08c00a..535847cf59 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs/scripts/config/plugins/fallback.ts
+++ b/packages/create-sitecore-jss/src/templates/nextjs/scripts/config/plugins/fallback.ts
@@ -1,4 +1,3 @@
-import chalk from 'chalk';
import { JssConfig } from 'lib/config';
import { ConfigPlugin } from '..';
@@ -11,19 +10,10 @@ class FallbackPlugin implements ConfigPlugin {
order = 100;
async exec(config: JssConfig) {
- if (config.sitecoreApiKey && config.sitecoreEdgeContextId) {
- console.log(
- chalk.yellow(
- "You have configured both 'sitecoreApiKey' and 'sitecoreEdgeContextId' values. The 'sitecoreEdgeContextId' is used instead."
- )
- );
- }
-
return Object.assign({}, config, {
defaultLanguage: config.defaultLanguage || 'en',
sitecoreApiKey: config.sitecoreApiKey || 'no-api-key-set',
layoutServiceConfigurationName: config.layoutServiceConfigurationName || 'default',
- sitecoreEdgeUrl: config.sitecoreEdgeUrl || 'https://edge-platform.sitecorecloud.io',
});
}
}
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/scripts/generate-config.ts b/packages/create-sitecore-jss/src/templates/nextjs/scripts/generate-config.ts
index 2369bc8f87..beca398a20 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs/scripts/generate-config.ts
+++ b/packages/create-sitecore-jss/src/templates/nextjs/scripts/generate-config.ts
@@ -14,8 +14,6 @@ import { jssConfigFactory } from './config';
const defaultConfig: JssConfig = {
sitecoreApiKey: process.env[`${constantCase('sitecoreApiKey')}`],
sitecoreApiHost: process.env[`${constantCase('sitecoreApiHost')}`],
- sitecoreEdgeUrl: process.env[`${constantCase('sitecoreEdgeUrl')}`],
- sitecoreEdgeContextId: process.env[`${constantCase('sitecoreEdgeContextId')}`],
siteName:
process.env[`${constantCase('siteName')}`] || process.env[`${constantCase('jssAppName')}`],
graphQLEndpointPath: process.env[`${constantCase('graphQLEndpointPath')}`],
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/src/Layout.tsx b/packages/create-sitecore-jss/src/templates/nextjs/src/Layout.tsx
index 80f6c90924..c3679bd1b0 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs/src/Layout.tsx
+++ b/packages/create-sitecore-jss/src/templates/nextjs/src/Layout.tsx
@@ -9,8 +9,6 @@ import {
import { getPublicUrl } from '@sitecore-jss/sitecore-jss-nextjs/utils';
import Navigation from 'src/Navigation';
import Scripts from 'src/Scripts';
-// The bundle imports external (BYOC) components into the app and makes sure they are ready to be used.
-import BYOC from 'src/byoc';
// Prefix public assets with a public URL to enable compatibility with Sitecore editors.
// If you're not supporting Sitecore editors, you can remove this.
@@ -34,7 +32,6 @@ const Layout = ({ layoutData, headLinks }: LayoutProps): JSX.Element => {
return (
<>
-
{fields.pageTitle.value.toString() || 'Page'}
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/src/lib/config.ts b/packages/create-sitecore-jss/src/templates/nextjs/src/lib/config.ts
index 88ec0aaa07..83a2596423 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs/src/lib/config.ts
+++ b/packages/create-sitecore-jss/src/templates/nextjs/src/lib/config.ts
@@ -4,8 +4,6 @@
export interface JssConfig extends Record {
sitecoreApiKey?: string;
sitecoreApiHost?: string;
- sitecoreEdgeUrl?: string;
- sitecoreEdgeContextId?: string;
siteName?: string;
graphQLEndpointPath?: string;
defaultLanguage?: string;
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/src/lib/graphql-client-factory/create.ts b/packages/create-sitecore-jss/src/templates/nextjs/src/lib/graphql-client-factory/create.ts
index bc76efc74f..b3bf7017bb 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs/src/lib/graphql-client-factory/create.ts
+++ b/packages/create-sitecore-jss/src/templates/nextjs/src/lib/graphql-client-factory/create.ts
@@ -1,7 +1,6 @@
import {
GraphQLRequestClientFactoryConfig,
- GraphQLRequestClient,
- getEdgeProxyContentUrl
+ GraphQLRequestClient
} from '@sitecore-jss/sitecore-jss-nextjs/graphql';
import { JssConfig } from 'lib/config';
@@ -13,18 +12,14 @@ import { JssConfig } from 'lib/config';
export const createGraphQLClientFactory = (config: JssConfig) => {
let clientConfig: GraphQLRequestClientFactoryConfig;
- if (config.sitecoreEdgeContextId) {
- clientConfig = {
- endpoint: getEdgeProxyContentUrl(config.sitecoreEdgeContextId, config.sitecoreEdgeUrl),
- };
- } else if (config.graphQLEndpoint && config.sitecoreApiKey) {
+ if (config.graphQLEndpoint && config.sitecoreApiKey) {
clientConfig = {
endpoint: config.graphQLEndpoint,
apiKey: config.sitecoreApiKey,
};
} else {
throw new Error(
- 'Please configure either your sitecoreEdgeContextId, or your graphQLEndpoint and sitecoreApiKey.'
+ 'Please configure your graphQLEndpoint and sitecoreApiKey.'
);
}
diff --git a/packages/create-sitecore-jss/src/templates/nextjs/src/lib/next-config/plugins/monorepo.js b/packages/create-sitecore-jss/src/templates/nextjs/src/lib/next-config/plugins/monorepo.js
index f1ce7c9a26..f6f54147ea 100644
--- a/packages/create-sitecore-jss/src/templates/nextjs/src/lib/next-config/plugins/monorepo.js
+++ b/packages/create-sitecore-jss/src/templates/nextjs/src/lib/next-config/plugins/monorepo.js
@@ -1,6 +1,3 @@
-const path = require('path');
-const CWD = process.cwd();
-
/**
* @param {import('next').NextConfig} nextConfig
*/
@@ -10,12 +7,6 @@ const monorepoPlugin = (nextConfig = {}) => {
if (options.isServer) {
config.externals = ['react', 'vertx', ...config.externals];
}
- // Monorepo support for @sitecore-feaas/clientside/react
- config.resolve.alias['@sitecore-feaas/clientside/react'] = path.resolve(
- CWD, options.isServer ?
- './node_modules/@sitecore-feaas/clientside/dist/node/react.cjs' :
- './node_modules/@sitecore-feaas/clientside/dist/browser/react.esm.js'
- );
// Overload the Webpack config if it was already overloaded
if (typeof nextConfig.webpack === 'function') {
diff --git a/packages/sitecore-jss/src/site/graphql-siteinfo-service.test.ts b/packages/sitecore-jss/src/site/graphql-siteinfo-service.test.ts
index d9c95db7d4..53f61b98a5 100644
--- a/packages/sitecore-jss/src/site/graphql-siteinfo-service.test.ts
+++ b/packages/sitecore-jss/src/site/graphql-siteinfo-service.test.ts
@@ -1,10 +1,17 @@
+/* eslint-disable no-unused-expressions */
/* eslint-disable @typescript-eslint/no-unused-vars */
-import { expect } from 'chai';
+import { expect, spy, use } from 'chai';
+import spies from 'chai-spies';
import nock from 'nock';
import { GraphQLSiteInfoService, GraphQLSiteInfoResult } from './graphql-siteinfo-service';
import { GraphQLRequestClient, PageInfo } from '../graphql';
+import debugApi from 'debug';
+import debug from '../debug';
+
+use(spies);
describe('GraphQLSiteInfoService', () => {
+ let debugNamespaces: string;
const endpoint = 'http://site';
const apiKey = 'some-api-key';
@@ -63,8 +70,23 @@ describe('GraphQLSiteInfoService', () => {
},
};
+ before(() => {
+ debugNamespaces = debugApi.disable();
+ debugApi.enable(debug.multisite.namespace);
+ });
+
+ beforeEach(() => {
+ spy.on(debug.multisite, 'log', () => true);
+ });
+
afterEach(() => {
nock.cleanAll();
+ spy.restore(debug.multisite);
+ delete process.env.SITECORE;
+ });
+
+ after(() => {
+ debugApi.enable(debugNamespaces);
});
const mockSiteInfoRequest = (response: { [key: string]: unknown }) => {
@@ -269,4 +291,16 @@ describe('GraphQLSiteInfoService', () => {
const resultCached = await service.fetchSiteInfo();
expect(resultCached).to.deep.equal([]);
});
+
+ it('should skip on XM Cloud', async () => {
+ process.env.SITECORE = 'true';
+ nock(endpoint)
+ .post('/')
+ .reply(200, emptyResponse);
+ const service = new GraphQLSiteInfoService({ apiKey: apiKey, endpoint: endpoint });
+ const result = await service.fetchSiteInfo();
+ expect(result).to.deep.equal([]);
+ expect(debug.multisite.log, 'log debug message').to.be.called.once;
+ expect(nock.isDone(), 'skip request').to.be.false;
+ });
});
diff --git a/packages/sitecore-jss/src/site/graphql-siteinfo-service.ts b/packages/sitecore-jss/src/site/graphql-siteinfo-service.ts
index 8c57ca256c..c0b87758f4 100644
--- a/packages/sitecore-jss/src/site/graphql-siteinfo-service.ts
+++ b/packages/sitecore-jss/src/site/graphql-siteinfo-service.ts
@@ -134,6 +134,10 @@ export class GraphQLSiteInfoService {
if (cachedResult) {
return cachedResult;
}
+ if (process.env.SITECORE) {
+ debug.multisite('Skipping site information fetch (building on XM Cloud)');
+ return [];
+ }
const results: SiteInfo[] = [];
let hasNext = true;
diff --git a/scripts/samples.json b/scripts/samples.json
index 2f647ccfa7..b0eb76be3a 100644
--- a/scripts/samples.json
+++ b/scripts/samples.json
@@ -22,10 +22,10 @@
},
{
"initializers": [
- "nextjs", "nextjs-styleguide", "nextjs-personalize"
+ "nextjs", "nextjs-styleguide", "nextjs-xmcloud"
],
"args": {
- "appName": "nextjs-styleguide-personalize",
+ "appName": "nextjs-styleguide-xmcloud",
"fetchWith": "GraphQL",
"prerender": "SSG"
}