← All notes
CMS Implementation4 min

An array index is not a stable edit path

Visual Editing only works when the click path still points at the same array item after someone reorders the list. Sanity's Content Source Maps can address sections by index or by _key. Index paths are cheap to generate and wrong the moment an editor drags a block. Prefer withKeyArraySelector — and make sure every object in an array actually has a stable _key — so Presentation opens the field you clicked, not the one that slid into its slot.

Indexes drift; keys do not

Sanity form paths learned this years ago: pets[1].name becomes someone else's name after a reorder. Visual Editing inherits the same problem. If the source map says sections[2].heading, and an editor moves that section to the top, the overlay still paints on whatever now sits at index 2.

withKeyArraySelector asks the Content Lake for paths like sections[_key=="abc"].heading. The overlay follows the object, not the position. That is the difference between click-to-edit and click-the-wrong-block.

We treat resultSourceMap: true as incomplete for Presentation. true keeps index selectors. The string withKeyArraySelector is the one that matches how Studio patches arrays.

Stega is not enough by itself

We already clean stega out of slugs, hrefs, and colors so parsers do not choke. That note is about string safety. This one is about path identity. You can stegaClean correctly and still open the wrong Portable Text block because the source map pointed at an index.

When stega.enabled is true, current @sanity/client versions request withKeyArraySelector for you. Manual source-map fetches, older clients, and custom overlay wiring still need the explicit option. Do not assume the default you copied from a 2023 snippet is still the safe one.

If you build edit URLs with resolveEditUrl, pass paths that already use keys — or let the source map that came from withKeyArraySelector drive the link. Feeding pictures[0].alt into a resolver after a reorder is how you get a Studio intent for the wrong image.

Migrations have to mint keys

Seed scripts and content migrations are where index thinking sneaks back in. createOrReplace with a deterministic document ID is good practice. Arrays of objects without _key — or with all-numeric keys that some tools misread as indexes — leave Presentation without a stable handle.

When we migrate notes, case studies, and homepage tiles, every section, FAQ, and source object gets an explicit _key derived from something stable in the source, not from its position in the JSON array. Re-running the migration must not reshuffle keys just because the file order changed.

Primitive arrays cannot carry keys. If editors need to click individual items, model them as objects with a value field and a _key. That is slightly more schema, and it is the cost of overlays that survive reordering.

How we verify overlays on real arrays

Open Presentation on a page with a sections array. Click the third heading. Confirm Studio lands on that section. Drag the section to the top in Studio, save, refresh the preview, click the same heading again. If the overlay now opens a different document path, you are on index selectors somewhere in the chain.

Repeat for nested arrays — FAQ items inside a note, gallery images inside a case study. Nested indexes fail the same way; nested keys do not.

Ship the key-based source map as the default for any preview client that feeds Visual Editing. Indexes are fine for one-shot debug dumps. They are not a field identity.

Have something to build?

Tell us what you're working on and we'll tell you honestly whether we're the right fit.

Work with us