Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Next.js] XMC Forms support without BYOC #2052

Merged
merged 5 commits into from
Mar 17, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ComponentBuilderPlugin, ComponentBuilderPluginConfig } from '..';

/**
* Provides Form component configuration
*/
class FormPlugin implements ComponentBuilderPlugin {
order = 1;

exec(config: ComponentBuilderPluginConfig) {
config.packages.push({
name: '@sitecore-jss/sitecore-jss-nextjs',
components: [
{
componentName: 'Form',
moduleName: 'Form',
},
],
});

return config;
}
}

export const formPlugin = new FormPlugin();
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ import * as FEAAS from '@sitecore-feaas/clientside/react';
* to reduce javascript bundle size.
*/

// SitecoreForm component displays forms created in XM Forms as individual components to be embedded into Pages.
// Sitecore Forms for Sitecore XP are still available separately via @sitecore-jss-forms package
import '@sitecore/components/form';

/**
* End of built-in JSS imports
* You can import your own client component below
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const monorepoPlugin = (nextConfig = {}) => {
'./node_modules/@sitecore-feaas/clientside/dist/browser/react.esm.js'
);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Workaround for "monorepo" setup, since we need to reference the same package

config.resolve.alias['@sitecore-cloudsdk/events'] = path.resolve(
CWD, './node_modules/@sitecore-cloudsdk/events'
);

// Overload the Webpack config if it was already overloaded
if (typeof nextConfig.webpack === 'function') {
return nextConfig.webpack(config, options);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { useEffect } from 'react';
<% if (prerender === 'SSG') { -%>
import { GetStaticPaths, GetStaticProps } from 'next';
<% } else if (prerender === 'SSR') { -%>
import { GetServerSideProps } from 'next';
<% } -%>
import NotFound from 'src/NotFound';
import Layout from 'src/Layout';
import {
SitecoreContext,
ComponentPropsContext,
<% if (prerender === 'SSG') { -%>
StaticPath,
<% } -%>
} from '@sitecore-jss/sitecore-jss-nextjs';
import { handleEditorFastRefresh } from '@sitecore-jss/sitecore-jss-nextjs/utils';
import { SitecorePageProps } from 'lib/page-props';
import { sitecorePagePropsFactory } from 'lib/page-props-factory';
import { componentBuilder } from 'temp/componentBuilder';
import config from 'temp/config';
<% if (prerender === 'SSG') { -%>
import { sitemapFetcher } from 'lib/sitemap-fetcher';

<% } -%>

const SitecorePage = ({ notFound, componentProps, layoutData, headLinks }: SitecorePageProps): JSX.Element => {
useEffect(() => {
// Since Sitecore editors do not support Fast Refresh, need to refresh editor chromes after Fast Refresh finished
handleEditorFastRefresh();
}, []);

if (notFound || !layoutData.sitecore.route) {
// Shouldn't hit this (as long as 'notFound' is being returned below), but just to be safe
return <NotFound />;
}

const isEditing = layoutData.sitecore.context.pageEditing;

return (
<ComponentPropsContext value={componentProps}>
<SitecoreContext
componentFactory={componentBuilder.getComponentFactory({ isEditing })}
layoutData={layoutData}
api={{
edge: {
contextId: config.sitecoreEdgeContextId,
edgeUrl: config.sitecoreEdgeUrl,
},
}}
Comment on lines +44 to +49
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a new file because of this portion

>
<Layout layoutData={layoutData} headLinks={headLinks} />
</SitecoreContext>
</ComponentPropsContext>
);
};

<% if (prerender === 'SSG') { -%>
// This function gets called at build and export time to determine
// pages for SSG ("paths", as tokenized array).
export const getStaticPaths: GetStaticPaths = async (context) => {
// Fallback, along with revalidate in getStaticProps (below),
// enables Incremental Static Regeneration. This allows us to
// leave certain (or all) paths empty if desired and static pages
// will be generated on request (development mode in this example).
// Alternatively, the entire sitemap could be pre-rendered
// ahead of time (non-development mode in this example).
// See https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration

let paths: StaticPath[] = [];
let fallback: boolean | 'blocking' = 'blocking';

if (process.env.NODE_ENV !== 'development' && process.env.DISABLE_SSG_FETCH?.toLowerCase() !== 'true') {
try {
// Note: Next.js runs export in production mode
paths = await sitemapFetcher.fetch(context);
} catch (error) {
console.log('Error occurred while fetching static paths');
console.log(error);
}

fallback = process.env.EXPORT_MODE ? false : fallback;
}

return {
paths,
fallback,
};
};

// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation (or fallback) is enabled and a new request comes in.
export const getStaticProps: GetStaticProps = async (context) => {
<% } else if (prerender === 'SSR') { -%>
// This function gets called at request time on server-side.
export const getServerSideProps: GetServerSideProps = async (context) => {
<% } -%>
const props = await sitecorePagePropsFactory.create(context);

return {
props,
<% if (prerender === 'SSG') { -%>
// Next.js will attempt to re-generate the page:
// - When a request comes in
// - At most once every 5 seconds
revalidate: 5, // In seconds
<% } -%>
notFound: props.notFound, // Returns custom 404 page with a status code of 404 when true
};
};

export default SitecorePage;
1 change: 0 additions & 1 deletion packages/sitecore-jss-angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
"@angular/platform-browser": "~18.2.13",
"@angular/platform-browser-dynamic": "~18.2.13",
"@angular/router": "~18.2.13",
"@sitecore-cloudsdk/events": "^0.4.2",
"@types/jasmine": "^5.1.4",
"@types/node": "^22.9.0",
"codelyzer": "^6.0.1",
Expand Down
Loading