Imagine you’re walking your dog/cat/sheep/child whatever and you come across a hole in the ground. It looks like some furry critter dug a hole. Nothing weird. Now you head over to examine a hole, and out pops a dolphin. You may say WTH. That’s kinda the same response I had yesterday when I solved this problem.
There’s a pretty (un)common knowledge out there: When working with Vercel, you are limited in the amount of data you can send in a payload at a time. It’s currently 4.5MB. And it’s a good reason: AWS has some limits as well. I believe it’s around 6MB, which gives Vercel a little wiggle room to play with. No biggie.
Anyway, we started seeing this error in our Experience Editor (running in Vercel…which may or may not be a great idea): Connection to your rendering host failed with a Payload Too Large. I popped over to postman and wanted to check how big the data actually was. It was…a paltry 700kB. Not tiny by any means, but not close to 4.5MB. Regardless, I heeded some sagely advance and stood up some Linux App Services to run my own Editing Host, pulling it from Vercel. While that it was its own fun adventure of learnings (side note: Compress-Archive and az webapp deployment is going to give you heartburn when you realize the build server is running a version of PS that isn’t smart enough to flip your slashes, leading your web app to crap the bed when trying to unzip. And then you go get 7zip standalone to do it..and it works… but whatever I’m not salty)
Back on topic, the App Service was setup and running, Sitecore was configured correctly to use it as the Editing Host….and the SAME error popped up. This was….not expected.
And then I dug. And dug. And dug. And then I drank a little…and dug more.
It turns out that the error noted was NOT in fact from Vercel. It was from NextJS! deep within the configs of the editing APIs were limits in place. What were those limits? Close to 4.5MB, right?
Here’s the contents of src\__APPLICATION__\src\pages\api\editing\render.ts
import { EditingRenderMiddleware } from '@sitecore-jss/sitecore-jss-nextjs/editing';
/**
* This Next.js API route is used to handle 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\sxastarter.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().getHandler();
export default handler;
And there’s also src\__APPLICATION__\src\pages\api\editing\data[key].ts
import { EditingDataMiddleware } from '@sitecore-jss/sitecore-jss-nextjs/editing';
/**
* This Next.js API route is used to handle Sitecore editor data storage and retrieval by key
* on serverless deployment architectures (e.g. 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().getHandler();
export default handler;
I figured it would be bigger. But it wasn’t. And I am disappointed.
So I changed both of those to 4MB, deployed, and voila..the problem is solved. Well, mostly. We wanted to test the practical limits, so we duped a bunch of renderings. When Vercel finally threw a 413 for us, it looked like this, in the log file:
[ERROR] [Someones_SSN] LAMBDA_RUNTIME Failed to post handler success response. Http response code: 413.
That makes more sense. Anyway, hope this helps steer you away from the dolphin hole I managed to swim down over the weekend.