Skip to content

Writing

FED-First Meets SitecoreAI — Updating Our Local Dev Story for 2026

Muhammad Ali Khan · 07 Nov 2026 · 06 Mins read

FED-First Meets SitecoreAI — Updating Our Local Dev Story for 2026

In February 2025 I wrote down why we had stopped booting a local XM Cloud in Docker for front-end work. The head ran on the developer's machine, the preview endpoint stayed in Sitecore's cloud, and we got Pages, forms, and real content without a Windows container. That post is still right about Docker. It is incomplete about everything Sitecore shipped around it in the following year. Content SDK replaced JSS as the supported SDK for the SaaS product. The page builder edits through field metadata. Agentic Studio can create items. None of those arrive on localhost by themselves, and a local dev story that still says "point JSS at the preview GraphQL endpoint" sends a new developer into the wrong starter.

This is the local setup I actually want someone to follow in November 2026. It is an update, not a retraction. The internet dependency I complained about in February is still the dependency. The machine is still just a Node process. What changed is the contract between that process and the page builder.


What I kept from the 2025 setup

We still do not run the CM locally to style a component. The SitecoreAI environment is the system of record for items, workflow, and Edge. The laptop runs the rendering app. That split is what made macOS and Linux normal for this work, and it is what keeps a new hire from needing a container host with half a dozen services before they can change a button.

We still need the network. Preview, editing, and the Cloud Portal do not have an offline mode I am willing to call supported. I still warn people who travel that way. I also still warn them that a local head pointed at a shared environment can confuse other authors if you publish from it. The discipline is the same as last year. Local is for rendering. The environment is for content. You do not "just publish" from a branch you have not merged.

We still keep secrets out of the client bundle. The February post was less strict about this than I am now, because the variable names changed and the blast radius changed with agents in the same organization. SITECORE_EDITING_SECRET is a server secret. Anything that was NEXT_PUBLIC_ is on purpose public. I do not put an automation client, a revalidate secret, or an editing secret in a public variable because the local app "needs to boot."


The page builder talks to localhost directly

Sitecore documents a local editing host for the page builder and Design Studio. From the editing host selector you choose Local host and you enter http://localhost:3000/. The documented support line for that feature starts at JSS 22.1 and the metadata editing method. Content SDK is the SDK I install now, and it speaks that method. Experience Editor chromes are gone. If a local setup guide still tells the developer to open Experience Editor against their machine, it is a JSS-era guide and I archive it.

Third-party cookies have to be allowed for the procedure Sitecore describes. I put that in the onboarding list, because a browser that blocks them produces a blank editing frame and a developer who starts rewriting middleware. The frame was never the bug.

Switching the selector back to the default editing host points the page builder at the shared deployed renderer again. I ask people to switch it back when they are done for the day. A selector left on one developer's localhost means every author on that site is editing through a process that is asleep. The symptom looks like Sitecore being down. It is a laptop lid.

When the local port is not 3000, Content SDK 1.1 and later take sitecoreInternalEditingHostUrl in sitecore.config.ts, or SITECORE_INTERNAL_EDITING_HOST_URL. The config file wins if both are set. The editing render route needs that value passed through. On a default next dev port I leave it unset and let the product default stand. I have burned an hour on a machine where the config still said 3001 and the dev server said 3000. The page builder was "connected." The internal render went nowhere.


The config file is the local story

sitecore.config.ts is the file I want a new developer to read on the first morning. The properties I make them set, and the environment variables that back them:

import { defineConfig } from "@sitecore-content-sdk/nextjs/config";

export default defineConfig({
  defaultSite: process.env.NEXT_PUBLIC_DEFAULT_SITE_NAME,
  defaultLanguage: process.env.NEXT_PUBLIC_DEFAULT_LANGUAGE,
  editingSecret: process.env.SITECORE_EDITING_SECRET,
  generateStaticPaths: false,
});

generateStaticPaths: false is deliberate on a machine used as an editing host, and on any deployed editing host. Sitecore's config reference says a SitecoreAI editing host should disable static path generation and lean on ISR or dynamic rendering. A local next dev that tries to prebuild every route against a shared tenant is slow and it is wrong. I want the route I am editing, not a tour of the content tree at startup.

editingSecret has to match the environment. A mismatch fails editing in a way that looks like a CORS problem if you only watch the browser. I compare the Deploy app or the environment variable store with .env.local before I compare anything else. The old name JSS_EDITING_SECRET is a leftover. Content SDK's guide uses SITECORE_EDITING_SECRET. Both can sit in an env file during a migration and the wrong one will be the one that is filled in.

The API host, the Edge platform hostname, the context id, and the API key are the connection. I keep them in .env.local, I keep .env.local out of git, and I point them at the non-production environment. A local app pointed at production preview is a supported kind of debugging and a bad default. Production content on a laptop also means production analytics if somebody left tracking enabled. I turn tracking off in development the same way I turn personalize off in development, with an explicit flag, not with a hope that localhost is invisible.

There is a disableCodeGeneration flag on the config for teams that are not using AI component generation. I set it when the repository is the source of components and nobody has asked for generated code. I do not leave a generator writing into src on a machine where an agent is also open. Two writers, one component file, no review. If we adopt generation later, we will turn the flag off in a pull request that names the folder it is allowed to touch.


Where agents fit, and where they do not

Agentic Studio can create a page item and place a rendering that already exists. It cannot compile the local Next.js app, and it cannot see a component that has not been registered in the component map and deployed or served from the local host the page builder is pointed at. The local loop I want is still: scaffold the component, register it, run npm run dev, point the page builder at localhost, place the rendering, edit a field, see metadata update in the frame, save, refresh preview.

sitecore-tools still has to run so the component map matches the files. I run it before next dev when the map is stale, and in CI before next build. A local host that serves an old map will show the developer a fallback component while the page builder offers the new rendering name. That looks like a Sitecore bug and it is a stale generated file.

Preview data and published data remain different. Saving in the page builder updates the item. The public Edge endpoint updates on publish. A local app configured for preview will show the save immediately and the production URL will not. I make the developer hit both URLs once during onboarding so they learn the difference with their own component, not during a launch.


The loop I write on the team wiki

  1. Clone the Content SDK app, install, and fill .env.local from the non-production environment. Editing secret, site name, language, Edge connection. No production automation secrets.
  2. Set generateStaticPaths off for this machine. Start npm run dev. Confirm a published page renders.
  3. In the page builder, select Local host, enter the dev origin, allow third-party cookies, and place a component this branch adds. Edit a field. Confirm the frame shows the local component, not the shared editing host.
  4. Save, check preview, and only then decide whether the item should be published. Switch the selector back to the default editing host when you stop the dev server.
  5. If the port or the internal render host is non-default, set sitecoreInternalEditingHostUrl and pass it to the editing render handler. If you are not using generated components, set disableCodeGeneration.

The February 2025 reason for this architecture still holds. We were spending our mornings on containers that could not even pretend to be the full XM Cloud service list. The November 2026 version of the same idea is a Content SDK process, a config file, and a page builder that knows the process is there. Agents and Spaces are how content arrives. They are not the local runtime. The local runtime is still the head, and it still has to be the head you pointed the editor at.

Related notes