Wednesday, 19 August 2026

A field note from shipping Sitecore Content SDK (App Router) on Vercel — where a custom-domain access restriction and an internal editing fetch collided into a cryptic 500.

One of those Sitecore issues that looks simple at first, but turns into a few hours of digging.

We had Sitecore Pages working perfectly against the open *.vercel.app URL, but the moment we switched to our protected custom domain, editing started failing with a rather unhelpful 500. The interesting part was that the problem wasn’t really Pages, Vercel, or the domain restriction on its own — it was how the Content SDK makes an internal request back to the app during editing.

Here’s what we found, and what finally fixed it.



The symptom

In Sitecore Pages, editing against our custom preview host failed with 500 on:

GET /api/editing/render?...&route=/Components&mode=edit

Vercel function logs showed:

TypeError: Failed to parse URL from /Components

Same app, same commit, same item — but pointed at the open *.vercel.app host — worked with no errors.



What /api/editing/render actually does

With Content SDK’s editing optimization, the render handler does not only set draft mode and redirect. It performs an internal server-side fetch of the page route and returns HTML to Pages.

By default, that internal host comes from the incoming request’s Host header (or from SITECORE_INTERNAL_EDITING_HOST_URL / sitecoreInternalEditingHostUrl when configured). Docs:



Two problems that look like one

1) Relative route + Node fetch

Pages sends route=/Components (relative). On the server, fetch('/Components') is invalid — Node needs an absolute URL. That produces exactly:

Failed to parse URL from /Components

This is not a 401/403 from your domain gate. It’s a URL construction failure before (or instead of) a successful loopback.

Community echo of the same class of error:

2) Domain restriction on the loopback

Even after the URL is absolute, if the internal fetch targets a restricted custom domain, it must carry the same bypass your editors use.

Sitecore’s official guidance for stock Vercel Deployment Protection uses x-vercel-protection-bypass on rendering-host URLs:

If you use a custom query bypass (for example a firewall rule keyed off a token query string), remember: Content SDK only forwards allow-listed params. Configure something like:

export const { GET, POST, OPTIONS } = createEditingRenderRouteHandlers({
  sitecoreInternalEditingHostUrl: scConfig.sitecoreInternalEditingHostUrl,
  allowedQueryParams: ['sitecore-editing-host'], // your bypass query name
});

Docs for allow-listing:

Why *.vercel.app “just worked”

Open preview host → Host header resolves → internal fetch gets an absolute URL → no restriction on that host → Pages happy.

Restricted custom domain → either absolute host isn’t applied (you see the parse-URL 500), or absolute host is applied but the loopback is blocked without the bypass (you’d typically see auth/firewall failures instead).

Long-term you don’t need to keep the *.vercel.app hostname. Point editing at the custom domain and make the loopback succeed there:

SITECORE_INTERNAL_EDITING_HOST_URL=https://your-custom-preview-domain.example

…and forward your bypass query/header on the internal request.

Minimal checklist
  1. Confirm the 500 text in Vercel logs (Failed to parse URL vs 401/403).
  2. Wire sitecoreInternalEditingHostUrl in sitecore.config.ts and pass it into createEditingRenderRouteHandlers.
  3. Set SITECORE_INTERNAL_EDITING_HOST_URL to the custom preview origin if Host-based default isn’t enough.
  4. Add your bypass query name to allowedQueryParams (or use Vercel’s official protection-bypass params on the rendering host).
  5. Retest Pages on the custom domain; retire the open *.vercel.app host when green.

Takeaway

Sitecore’s editing render path is a server-to-server call inside your Next app. Anything that assumes “the browser already passed the gate” will miss the loopback. Absolute internal host + bypass on that second hop is what makes a restricted custom domain behave like the open Vercel URL.

If this saved you an afternoon of log diving, share it with the next person staring at Failed to parse URL from /YourPage in a Pages session.

No comments:

Post a Comment