About content references
A Reference field points one content entry at another. Why a pointer, when Picked can put the content into the entry that needs it?
A pointer keeps one fact in one place
A product points at its category. Ten products can point at the same category.
A copy makes ten categories. Correct the name of the category and you must correct it ten times. The copy that you do not correct is now wrong.
A pointer makes one category. Correct the name one time, and every product that points at it is correct.
This is the same reason that Blocks exist, one level up. A Block shares a shape between entries. A reference shares an entry between entries.
The target travels beside the content
Picked sends the entries of your steps in content. It sends the entries that a
reference reaches in references. Both go into the same content index in the SDK, keyed
by the id.
Picked can put the target inside the field instead, and it did so before. Three things count against that.
A shared target costs one blob, and not one blob for each entry that points at it. Ten products with the same category send the category one time.
A separate entry has an id. Your code reads it with useContent(id), and live preview
updates it while you edit. A target inside a field has no id, so an update finds nothing
to change.
The reader chooses how deep to go. A component that shows a category reads the category. A component that shows a card reads the product only, and it costs nothing more.
Picked stops a chain at a depth of five
Content can point at content that points at content. Such a chain has no end of its own. A cycle has none at all. Two entries that point at each other keep the chain open for as long as something asks.
Picked therefore resolves a chain to a depth of five. It counts the depth from the entries that your steps point at. It also keeps the entries that it saw, so that a cycle stops.
Five is a choice, and not a rule of the system. It is deep enough for the shapes that content takes, such as a product, its category, and the owner of that category. It is also small enough that one page cannot pull a whole workspace over the wire.
A missing entry is how Picked says "no such entry"
Picked sends no blob for a pointer whose target it cannot resolve. The entry is absent
from references.
The other option is a blob with no data. That reads as an entry that exists and is empty, which is a different fact from an entry that is not there.
Your code cannot tell one from the other. The empty record also goes into the content index under an id that resolves. A missing entry looks like nothing else.
A delete stops while a reference is live
Picked does not delete an entry that another entry points at. It does not delete a Model that a Reference field holds as its target.
The other option is a pointer at nothing. Picked must then choose what the field holds, and every answer is wrong. It can give your component an empty value that the component does not expect. It can also remove content that somebody wrote, with no report.
A stop costs you one step. Clear the reference, then delete the target. In return, a field that holds a pointer always points at something that exists.
A reference stays inside its workspace
A field cannot point at an entry in another workspace. Picked reports such a target as unknown.
A workspace is one version of the configuration of a project, and you publish it whole. A pointer that leaves the workspace resolves against content that this workspace never sent. The two sides can then go live at different times.
The delivery surface applies the same rule on a read, so a target outside the workspace never reaches a visitor.
Related
- Models — the field and its options.
- Content entries — the editor and the delete rules.
- Content — how your code resolves a pointer.
- Experience content endpoint — the wire shape.
- About the content model — why a schema and its data are separate.
