Override the default directory used by the disk-based editing cache implementation

Current version: 22.x

The disk-based cache used for integrating JSS Next.js apps with advanced Sitecore content and layout editors uses, by default, the operating system temp directory. When hosting your Next.js application on Vercel, the default temp directory works fine. However, on other platforms, using the default temp directory can cause the editing data middleware to malfunction, resulting in intermittent 500 errors in Experience Editor.

You must override the directory used for the disk-based cache to resolve the errors.

To override the default temp directory:

  1. In a new file, for example, /src/lib/editing.ts, create an editing data disk cache, overriding the default temp directory with one of your choosing and a new editing data service that uses the new cache:

    RequestResponse
    import {
      EditingDataDiskCache,
      BasicEditingDataService,
      ServerlessEditingDataService
    } from '@sitecore-jss/sitecore-jss-nextjs/editing';
    
    // Override the default editingDataDiskCache with an accessible temp directory
    export const myEditingDataDiskCache = new EditingDataDiskCache('C:\\temp');
    
    // Override default editingDataService to use myEditingDataDiskCache for BasicEditingDataService
    export const myEditingDataService = process.env.VERCEL
      ? new ServerlessEditingDataService()
      : new BasicEditingDataService({
          editingDataCache: myEditingDataDiskCache,
        });
  2. In the /src/pages/api/editing/data/[key].ts file, update the EditingDataMiddleware handler to use the new editing data disk cache:

    RequestResponse
    import { EditingDataMiddleware } from '@sitecore-jss/sitecore-jss-nextjs/editing';
    import { myEditingDataDiskCache } from 'lib/editing';
    
    /**
     * This Next.js API route is used to handle Sitecore editor data storage and retrieval by key
     * on serverless deployment architectures (such as Vercel) via the `ServerlessEditingDataService`.
     * The `EditingDataMiddleware` expects this dynamic route name to be '[key]' by default but can
     * be configured to use something else with the `dynamicRouteKey` option. 
    */
    
    // Bump body size limit (1mb by default) and disable response limit for Sitecore editor payloads
    // See https://nextjs.org/docs/api-routes/request-helpers#custom-config
    export const config = {
      api: {
        bodyParser: {
          sizeLimit: '2mb',
        },
        responseLimit: false,
      },
    };
    
    // Wire up the EditingDataMiddleware handler
    const handler = new EditingDataMiddleware({
      editingDataCache: myEditingDataDiskCache,
    }).getHandler();
    
    export default handler;
  3. In the /src/pages/api/editing/render.ts file, update the existing handler with a new instance of the EditingRenderMiddleware class that uses the new editing data service:

    RequestResponse
    import { EditingRenderMiddleware } from '@sitecore-jss/sitecore-jss-nextjs/editing';
    import { myEditingDataService } from 'lib/editing';
    
    /** * This Next.js API route handles POST requests from Sitecore editors.
     * This route should match the `serverSideRenderingEngineEndpointUrl` in your Sitecore configuration,
     * which is set to "http://localhost:3000/api/editing/render" by default (see \sitecore\config\nextjs-app.config).
     * * The `EditingRenderMiddleware` will *  1. Extract editing data from the Sitecore editor POST request
     *  2. Stash this data (for later use in the page render request) via an `EditingDataService`, which returns a key for retrieval
     *  3. Enable Next.js Preview Mode, passing our stashed editing data key as preview data
     *  4. Invoke the actual page render request, passing along the Preview Mode cookies.
     *     This allows retrieval of the editing data in preview context (via an `EditingDataService`) - see `SitecorePagePropsFactory`
     *  5. Return the rendered page HTML to the Sitecore editor
     */
    
    // Bump body size limit (1mb by default) and disable response limit for Sitecore editor payloads
    // See https://nextjs.org/docs/api-routes/request-helpers#custom-config
    export const config = {
      api: {
        bodyParser: {
          sizeLimit: '2mb',
        },
        responseLimit: false,
      },
    };
    
    // Wire up the EditingRenderMiddleware handler
    const handler = new EditingRenderMiddleware({
      editingDataService: myEditingDataService,
    }).getHandler();
    
    export default handler;
  4. Update the src/lib/page-props-factory/plugins/preview-mode.ts file so that the PreviewModePlugin class uses the new editing data service:

    RequestResponse
    import { myEditingDataService } from 'lib/editing';
    import { SitecorePageProps } from 'lib/page-props';
    import { GetServerSidePropsContext, GetStaticPropsContext } from 'next';
    import { Plugin } from '..';
    
    class PreviewModePlugin implements Plugin {
      order = 0;
      
    async exec(props: SitecorePageProps, context: GetServerSidePropsContext | GetStaticPropsContext) {
        if (!context.preview) return props;
        
        // If we're in preview (editing) mode, use data already sent along with the editing request
        const data = await myEditingDataService.getEditingData(context.previewData);
        
        if (!data) {
          throw new Error(
            `Unable to get editing data for preview ${JSON.stringify(context.previewData)}`
          );
        }
        props.locale = data.language;
        props.layoutData = data.layoutData;
        props.dictionary = data.dictionary;
        return props;
      }
    }
    
    export const previewModePlugin = new PreviewModePlugin();

Do you have some feedback for us?

If you have suggestions for improving this article,