---
title: "Upgrade JSS 22.0.0 Next.js apps to version 22.1"
slug: "upgrade-jss-22-0-0-next-js-apps-to-version-22-1"
abstract: "How to upgrade your JavaScript Rendering SDKs to version 22.1 to make use of the latest features, including page speed optimization with metadata-based visual editing in Pages."
---
# Upgrade JSS 22.0.0 Next.js apps to version 22.1

This topic covers most of the changes you must make to your existing JSS 22.0.0 applications to take advantage of the new features in version 22.1, including [metadata-based editing for Pages](https://doc.sitecore.com/sai/en/developers/jss/22/jss-sai/editor-integration-using-metadata.html "Editor integration using metadata"). However, because of the nature of JavaScript and Next.js application development, this topic doesn't account for all the customization you might have in your existing application.

> [!important]
> The new metadata-based editing architecture provides improved page speeds when visually editing in Pages. It's also significantly easier to configure and maintain than the older, chromes-based architecture. As such, we strongly recommend updating all your apps to use metadata editing mode. The metadata mode is enabled by default for all new apps created from the JSS 22.1 starter kit.

While upgrading, consider the JSS templates and add-ons you used when creating your Next.js application. You can find them in your `package.json` file. For example, a JSS 22.0.0 application included in the XM Cloud starter foundation uses the following templates and add-ons:

> [!note]
> **XM Cloud is now SitecoreAI**
> Some code examples, images, and UI labels may still use XM Cloud while engineering assets are being updated.

- `nextjs` 
- `nextjs-xmcloud` 
- `nextjs-sxa` 
- `nextjs-multisite` 

> [!note]
> **Before you begin**
> -   If you haven't already done so, [upgrade your app to JSS 22.0.0](https://doc.sitecore.com/sai/en/developers/jss/22/jss-sai/upgrade-jss-21-7-next-js-apps-to-version-22-0-0.html "Upgrade JSS 21.7 Next.js apps to version 22.0.0").
>
> -   Familiarize yourself with the [changelog](https://github.com/Sitecore/jss/releases/tag/v22.1.0). If your application is heavily customized, the changelog can provide guidance on what additional changes you need that are not covered in this topic.

This topic describes how to:

:::walkthrough
1. [Update application dependencies in your existing app](https://doc.sitecore.com/sai/en/developers/jss/22/jss-sai/upgrade-jss-22-0-0-next-js-apps-to-version-22-1.html#update-application-dependencies-in-your-existing-app)
2. [Create a JSS 22.1 Next.js application](https://doc.sitecore.com/sai/en/developers/jss/22/jss-sai/upgrade-jss-22-0-0-next-js-apps-to-version-22-1.html#create-a-jss-221-nextjs-application)
3. [Update the Next.js template files in your existing app](https://doc.sitecore.com/sai/en/developers/jss/22/jss-sai/upgrade-jss-22-0-0-next-js-apps-to-version-22-1.html#update-the-nextjs-template-files-in-your-existing-app)
4. [Update the XM Cloud add-on](https://doc.sitecore.com/sai/en/developers/jss/22/jss-sai/upgrade-jss-22-0-0-next-js-apps-to-version-22-1.html#update-the-xm-cloud-add-on)
5. [Update the SXA add-on](https://doc.sitecore.com/sai/en/developers/jss/22/jss-sai/upgrade-jss-22-0-0-next-js-apps-to-version-22-1.html#update-the-sxa-add-on)
:::

## Update application dependencies in your existing app

For your upgraded application to work correctly, you will need to update dependencies.

To update your dependencies:

1. In your existing application's `package.json` file:
    - Update every `@sitecore-jss` package to version `~22.1`.
    - Update the `@sitecore-cloudsdk/events` package to version `^0.3.1`.
    - Update the `@types/node` package to version `^20.14.2`.
2. Install the dependencies with the following command:

    ```shell
    npm install
    ```

3. We highly recommend you install version `0.32.6` of the `sharp` image processing library using the following command. This is to improve memory usage of the image optimization feature:

    ```shell
    npm i sharp@0.32.6
    ```

## Create a JSS 22.1 Next.js application

To simplify the upgrade process as much as possible, create a JSS 22.1 Next.js application with the XM Cloud add-on. You can then copy some files from this app into your existing app.

To create a JSS 22.1 Next.js application with the XM Cloud add-on included:

1. In a console, run the following command:

    ```shell
    npx create-sitecore-jss@22.1 nextjs
    ```

2. If prompted to install the `create-sitecore-jss@22.1` package, answer *y*.
3. Enter the folder path for the JSS 22.1 Next.js app. For example, enter `*./jss221*`, to create the app folder in your current working directory.
4. Follow the remaining prompts, selecting the same options for data fetching (`GraphQL` or `REST`) and prerendering (`SSG` or `SSR`) as in your existing application.
5. When asked if you are building for Sitecore XM Cloud, answer *y* to install the XM Cloud add-on.
6. Select other add-ons used by your existing application and press Enter.

The script then installs the application dependencies.

> [!note]
> **XM Cloud is now SitecoreAI**
> Some code examples, images, and UI labels may still use XM Cloud while engineering assets are being updated.

## Update the Next.js template files in your existing app

This explains how to synchronize files in your existing application with corresponding files from your new JSS 22.1 app.

To update the Next.js template files:

1. If you have not customized the `scripts/generate-config.ts` file, replace it with the 22.1 version. Otherwise, modify your file as follows:
    - In the `configText` prop assignment, add a `trim` method call after `config[prop]?`, such as:

        ```ts
        config[prop]?.trim()
        ```

    - At the end of that assignment, replace the comma before the newline character with a semicolon:

        ```ts
        // Before
        }',\n`;

        // After
        }';\n`;
        ```

    Here's an example of the updated assignment suitable for JSS 22.1:

    ```ts
    configText += `config.${prop} = process.env.${constantCase(prop)} || '${config[prop]?.trim()}';\n`;
    ```

2. If you have not customized the `lib/next-config/plugins/cors-header` plugin, replace it with the 22.1 version. Otherwise, modify your file as follows:
    - Because cross-origin resource sharing (CORS) is now handled by API handlers or middleware, remove the following CORS header for API endpoints:

        ```csharp
        {
          source: '/api/:path*',
          headers: [
            {
              key: 'Access-Control-Allow-Origin',
              value: config.sitecoreApiHost.replace(/\/$/, ''),
            },
          ],
        },
        ```

3. Because `ComponentConsumerProps` has been removed, if you have any `import` statements that reference it, update them all to use `WithSitecoreContextProps` instead.
4. Because the `resolvePageUrl` function now accepts an object, and because `serverUrl` is now optional, the latter is omitted if the metadata edit mode for Pages is enabled. If you've customized the `pages/api/editing/render.ts` file and you currently pass the `resolvePageUrl` function into `EditingRenderMiddleware`, modify your file as follows:
    - Replace the existing handler initialization with the following:

        ```ts
        const handler = new EditingRenderMiddleware({
          resolvePageUrl: ({ serverUrl, itemPath }) => `${serverUrl}${itemPath}`,
        }).getHandler();
        ```

    > [!note]
    > If you haven't customized `pages/api/editing/render.ts`, you don't need to make any new changes to it for this release.

5. If your app contains any references to the now-deprecated `EditingComponentPlaceholder` or the `RenderingType` enum, such as the following example in `[[...path]].tsx`, delete them:

    ```ts
    import Layout from 'src/Layout';
    import { RenderingType, EditingComponentPlaceholder } from '@sitecore-jss/sitecore-jss-nextjs';
    ...
    const isComponentRendering =
      layoutData.sitecore.context.renderingType === RenderingType.Component;
    ...
    {isComponentRendering ? (
      <EditingComponentPlaceholder rendering={layoutData.sitecore.route} />
    ) : (
      <Layout layoutData={layoutData} headLinks={headLinks} />
    )}
    ```

6. If you use the `next/image` component (instead of built-in JSS components such as `Image`, `Banner`, and so on) to render Sitecore images, we recommend you configure it to conditionally disable Next.js image optimization in edit and preview modes.

    > [!note]
    > This process is not necessary when using `next/image` to load static images or images from external sources.

    The following example describes one way you can implement conditional optimization, involving fetching the page state and using it to dynamically initialize a prop named `unoptimized`:

    - In your custom code (such as a custom component), add a new `import` statement together with two new definitions, as follows:

        ```js
        import { useSitecoreContext } from '@sitecore-jss/sitecore-jss-nextjs';
        ...
        const { sitecoreContext } = useSitecoreContext();
        const unoptimized = sitecoreContext.pageState !== LayoutServicePageState.Normal;
        ```

    - In your `next/image` component, add the following rendering that includes the newly-defined `unoptimized` prop:

        ```js
        <Image {...props} unoptimized={unoptimized}/>
        ```

    > [!note]
    > Built-in JSS components use conditional image optimization by default.

## Update the XM Cloud add-on

To update the XM Cloud add-on:

> [!note]
> **XM Cloud is now SitecoreAI**
> Some code examples, images, and UI labels may still use XM Cloud while engineering assets are being updated.

1. If you have not customized the `/src/Scripts.tsx` file, replace it with the 22.1 version. Otherwise, modify it as follows:
    - Add the following `import` statement:

        ```ts
        import { EditingScripts } from '@sitecore-jss/sitecore-jss-nextjs';
        ```

    - Add an `EditingScripts` component:

        ```typescript
        <EditingScripts />
        ```

    Here's an example of the updated file suitable for JSS 22.1:

    ```ts
    import { EditingScripts } from '@sitecore-jss/sitecore-jss-nextjs';

    const Scripts = (): JSX.Element | null => (
      <>
        <EditingScripts />
        ...
      </>
    );
    ```

2. If you have not customized the `/src/lib/dictionary-service-factory.ts` file, replace it with the 22.1 version. Otherwise, modify it as follows:
    - Add the `useSiteQuery` parameter to the `GraphQLDictionaryService` initialization:

        ```ts
        useSiteQuery: true,
        ```

    Here's an example of the updated initialization suitable for JSS 22.1:

    ```ts
    new GraphQLDictionaryService({
      siteName,
      clientFactory,
      ...
      useSiteQuery: true,
    })
    ```

3. If you have not customized the `/lib/page-props-factory/plugins/personalize.ts` file, replace it with the 22.1 version. Otherwise, modify it as follows:
    - Update the `personalizeLayout` function call to pass `personalizeData.componentVariantIds` as a parameter, such as:

        ```ts
        // Get variant(s) for personalization (from path)
        const personalizeData = getPersonalizedRewriteData(path);

        // Modify layoutData to use specific variant(s) instead of default
        // This will also set the variantId on the Sitecore context so that it is accessible here
        personalizeLayout(
          props.layoutData,
          personalizeData.variantId,
          personalizeData.componentVariantIds
        );
        ```

4. If you have not customized the `/lib/page-props-factory/plugins/preview-mode.ts` file, replace it with the 22.1 version. Otherwise, modify it as follows:
    - Prepare `personalizeData.componentVariantIds` and add it as a parameter of the `personalizeLayout` function call, such as:

        ```ts
        import {
            SiteInfo,
            personalizeLayout,
            getGroomedVariantIds,
        } from '@sitecore-jss/sitecore-jss-nextjs';
        ...
        props.headLinks = [];
        const personalizeData = getGroomedVariantIds(variantIds);
        personalizeLayout(
            props.layoutData,
            personalizeData.variantId,
            personalizeData.componentVariantIds
        );
        ```

5. If you have not customized the `lib/middleware/plugins/personalize.ts` file, replace it with the 22.1 version. Otherwise, modify it as follows:
    - In the `personalizeMiddleware` constructor signature, locate the following line within `edgeConfig` if present:

        ```ts
        scope: process.env.NEXT_PUBLIC_PERSONALIZE_SCOPE,
        ```

    - If it is present, move that line to the root of the constructor signature, outside of `edgeConfig`.

    Here's an example of the updated constructor signature suitable for JSS 22.1:

    ```ts
    this.personalizeMiddleware = new PersonalizeMiddleware({
      ...
      edgeConfig: {
        ...
      },
      scope: process.env.NEXT_PUBLIC_PERSONALIZE_SCOPE,
    });
    ```

    > [!important]
    > Keeping this `scope` within `edgeConfig` will continue to work for now, but this approach is deprecated and will no longer be supported after the next major release of JSS.

6. (Optional) Specify the edit mode used for Pages. If not specified, this is set to `EditMode.Metadata` by default.

    > [!important]
    > With the introduction of editing metadata architecture for Pages, JSS now uses metadata for editing as standard. We strongly recommend you use this new method to take advantage of faster page speeds and simpler configuration. If, however, you want to continue using the older, chromes-based editing architecture for now, you can manually apply this setting.

    To specify the edit mode, make the following changes to your `\src\pages\api\editing\config.ts` file:

    - Add the following `import` statement:

        ```ts
        import { EditMode } from '@sitecore-jss/sitecore-jss-nextjs';
        ```

    - In the `handler` definition, add one of the following property assignments based on your preferred editing method:

        ```typescript
        // Use only one of the following

        pagesEditMode: EditMode.Metadata, // Newer, recommended method (default)

        pagesEditMode: EditMode.Chromes, // Older method
        ```

    Here's an example of the updated definition specifically using metadata, suitable for JSS 22.1:

    ```ts
    const handler = new EditingConfigMiddleware({
      ...
      pagesEditMode: EditMode.Metadata,
    }).getHandler();
    ```

    > [!important]
    > If you've decided to use the new metadata architecture, you will also need to follow the rest of the steps in this section; otherwise, you can skip those steps and proceed to [update the SXA add-on](https://doc.sitecore.com/sai/en/developers/jss/22/jss-sai/upgrade-jss-22-0-0-next-js-apps-to-version-22-1.html#UUID-ae9deb24-1652-b686-36f8-2f7b1c198bfd_N1722528987695 "Update the SXA add-on").

7. Copy the `lib/graphql-editing-service.ts` file from your new 22.1 app into your existing app.
8. If you have not customized the `lib/page-props-factory/plugins/preview-mode.ts` file, replace it with the 22.1 version. Otherwise, modify it as follows:
    - Ensure your file imports all of the following classes and functions required for metadata editing integration:

        ```ts
        import {
          SiteInfo,
          personalizeLayout,
          getGroomedVariantIds,
        } from '@sitecore-jss/sitecore-jss-nextjs';
        import {
          editingDataService,
          isEditingMetadataPreviewData,
        } from '@sitecore-jss/sitecore-jss-nextjs/editing';
        import { graphQLEditingService } from 'lib/graphql-editing-service';
        ...
        ```

    - In the `PreviewModePlugin` class declaration, locate the existing `data` assignment, such as:

        ```ts
        const data = await editingDataService.getEditingData(context.previewData);
        ```

    - Immediately before that assignment, add the following new condition for processing editing page props in metadata mode:

        ```ts
        ...

        // If we're in Pages preview (editing) Metadata Edit mode, prefetch the editing data

        if (isEditingMetadataPreviewData(context.previewData)) {
          const { site, itemId, language, version, variantIds } = context.previewData;
          const data = await graphQLEditingService.fetchEditingData({
            siteName: site,
            itemId,
            language,
            version,
          });

          if (!data) {
            throw new Error(
              `Unable to fetch editing data for preview ${JSON.stringify(context.previewData)}`
            );
          }

          props.site = data.layoutData.sitecore.context.site as SiteInfo;
          props.locale = context.previewData.language;
          props.layoutData = data.layoutData;
          props.dictionary = data.dictionary;
          props.headLinks = [];
          const personalizeData = getGroomedVariantIds(variantIds);
          personalizeLayout(
            props.layoutData,
            personalizeData.variantId,
            personalizeData.componentVariantIds
          );

          return props;
        }

        ...
        ```

    - We recommend you update the code comment in front of the older assignment statement to differentiate it from the new addition, such as:

        ```ts
        // If we're in preview (editing) Chromes Edit mode, use data already sent along with the editing request
        // This mode is used by the Experience Editor.
        // In Pages it's treated as a legacy mode but is still supported for backward compatibility.

        const data = await editingDataService.getEditingData(context.previewData);
        ...
        ```

9. For metadata-based editing in Pages, the `field.editable` property has been superseded by `field.metadata`. If you have any custom field components that refer to `field.editable`, you need to rework your custom code to replace those references.

    > [!note]
    > Experience Editor and chromes-based editing still relies on `field.editable`.

## Update the SXA add-on

To upgrade the SXA add-on:

- Replace the following files with the new versions from your 22.1 app:
    - `src/components/Image.tsx` 
    - `src/components/Promo.tsx` 
    - `src/components/Title.tsx` 
    - `src/assets/sass/components/title/_component-title.scss` 

## Replace the import path for editing utilities

We're moving all editing utilities currently located at `@sitecore-jss/sitecore-jss/utils`, so if you currently refer to this path in any of your `import` statements you will need to update them to use the new path `@sitecore-jss/sitecore-jss/editing` instead.

This change affects the following utilities:

- `ChromeCommand` 
- `DefaultEditFrameButton` 
- `DefaultEditFrameButtonIds` 
- `DefaultEditFrameButtons` 
- `EditButtonTypes` 
- `EditFrameDataSource` 
- `ExperienceEditor` 
- `FieldEditButton` 
- `handleEditorAnchors` 
- `HorizonEditor` 
- `isEditorActive` 
- `mapButtonToCommand` 
- `Metadata` 
- `resetEditorChromes` 
- `WebEditButton` 

> [!warning]
> The older path will only continue to work until the next release of JSS. Therefore, we strongly recommend you make the necessary changes as soon as possible.

## Next steps

To finalize the upgrade process, make sure you resolve any errors and warnings you encounter. [Enable debug logging for JSS specific issues](https://doc.sitecore.com/sai/en/developers/jss/217/jss-sai/debug-logging-in-jss-apps.html) to assist you if necessary.

Certain header configurations can prevent metadata integration from working. To avoid this issue, make sure your response headers allow the Pages domain to load responses inside an iframe.