Repository: Thinkmill/keystatic
Pull request #101 (2023-02-24 06:40:39)

Remove old relationship field and inline relationships

changeset-bot[bot]: ###  ⚠️  No Changeset found

Latest commit: 944bb1cc5d464568aa0e3b590d0028fc32fab12d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. **If these changes should result in a version bump, you need to add a changeset.**

<details><summary>This PR includes no changesets</summary>

  When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

</details>

[Click here to learn what changesets are, and how to add one](https://github.com/changesets/changesets/blob/master/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add a changeset to this PR](https://github.com/Thinkmill/keystatic/new/remove-old-relationship-field?filename=.changeset/cold-buses-approve.md&value=---%0A%22%40keystatic%2Ftest-next-app%22%3A%20patch%0A%22%40keystatic%2Fcore%22%3A%20patch%0A%22%40keystatic%2Ftest-next-pages-dir%22%3A%20patch%0A---%0A%0ARemove%20old%20relationship%20field%20and%20inline%20relationships%0A)


vercel[bot]: [vc]: #5d+M3D1mqnnQ9vU3eQDKH49bOvE43doGZH869NIr8Xk=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJ2b3Vzc29pciIsInJvb3REaXJlY3RvcnkiOiJkZXNpZ24tc3lzdGVtL2RvY3MiLCJsaXZlRmVlZGJhY2siOnsicmVzb2x2ZWQiOjAsInVucmVzb2x2ZWQiOjAsInRvdGFsIjowLCJsaW5rIjoidm91c3NvaXItZ2l0LXJlbW92ZS1vbGQtcmVsYXRpb25zaGlwLWZpZWxkLXRoaW5rbWlsbC52ZXJjZWwuYXBwIn0sImluc3BlY3RvclVybCI6Imh0dHBzOi8vdmVyY2VsLmNvbS90aGlua21pbGwvdm91c3NvaXIvQUZqcVFyYzhuRHR3NmdYVzVEbmp6ZFlVQnUydiIsInByZXZpZXdVcmwiOiJ2b3Vzc29pci1naXQtcmVtb3ZlLW9sZC1yZWxhdGlvbnNoaXAtZmllbGQtdGhpbmttaWxsLnZlcmNlbC5hcHAiLCJuZXh0Q29tbWl0U3RhdHVzIjoiREVQTE9ZRUQifV19
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated |
| :--- | :----- | :------ | :------- | :------ |
| **voussoir** | ✅ Ready ([Inspect](https://vercel.com/thinkmill/voussoir/AFjqQrc8nDtw6gXW5DnjzdYUBu2v)) | [Visit Preview](https://voussoir-git-remove-old-relationship-field-thinkmill.vercel.app) | 💬 [**Add your feedback**](https://vercel.live/open-feedback/voussoir-git-remove-old-relationship-field-thinkmill.vercel.app) | Feb 24, 2023 at 6:41AM (UTC) |



Patch:
diff --git a/apps/next-pages-dir/local-config.tsx b/apps/next-pages-dir/local-config.tsx
index dbdb1aa2..5c019185 100644
--- a/apps/next-pages-dir/local-config.tsx
+++ b/apps/next-pages-dir/local-config.tsx
@@ -153,7 +153,6 @@ export default config({
                   formatting: 'inherit',
                   dividers: 'inherit',
                   links: 'inherit',
-                  relationships: 'inherit',
                 }),
               },
               toolbar({ props, onRemove }) {
diff --git a/keystatic/local-config.tsx b/keystatic/local-config.tsx
index e3b3672c..53118fc2 100644
--- a/keystatic/local-config.tsx
+++ b/keystatic/local-config.tsx
@@ -160,7 +160,6 @@ export default config({
                   formatting: 'inherit',
                   dividers: 'inherit',
                   links: 'inherit',
-                  relationships: 'inherit',
                 }),
               },
               toolbar({ props, onRemove }) {
diff --git a/packages/keystatic/DocumentEditor/block-markdown-shortcuts.ts b/packages/keystatic/DocumentEditor/block-markdown-shortcuts.ts
index c27be107..4ba04bd2 100644
--- a/packages/keystatic/DocumentEditor/block-markdown-shortcuts.ts
+++ b/packages/keystatic/DocumentEditor/block-markdown-shortcuts.ts
@@ -27,7 +27,6 @@ export function withBlockMarkdownShortcuts(
   const editorDocumentFeaturesForNormalizationToCheck: DocumentFeaturesForNormalization =
     {
       ...documentFeatures,
-      relationships: true,
     };
   let addShortcut = (
     text: string,
diff --git a/packages/keystatic/DocumentEditor/component-blocks/api.tsx b/packages/keystatic/DocumentEditor/component-blocks/api.tsx
index 82c52fe5..d10fb8f2 100644
--- a/packages/keystatic/DocumentEditor/component-blocks/api.tsx
+++ b/packages/keystatic/DocumentEditor/component-blocks/api.tsx
@@ -53,8 +53,6 @@ export type FormFieldValue =
   | readonly FormFieldValue[]
   | { [key: string]: FormFieldValue | undefined };
 
-const emptyObject = {};
-
 type FormattingConfig = {
   inlineMarks?:
     | true
@@ -364,7 +362,6 @@ export type ChildField = {
         formatting?: BlockFormattingConfig;
         dividers?: 'inherit';
         links?: 'inherit';
-        relationships?: 'inherit';
       }
     | {
         kind: 'inline';
@@ -374,7 +371,6 @@ export type ChildField = {
           softBreaks?: 'inherit';
         };
         links?: 'inherit';
-        relationships?: 'inherit';
       };
 };
 
@@ -387,14 +383,6 @@ export type ArrayField<ElementField extends ComponentSchema> = {
   asChildTag?: string;
 };
 
-export type RelationshipField<Many extends boolean> = {
-  kind: 'relationship';
-  listKey: string;
-  selection: string | undefined;
-  label: string;
-  many: Many;
-};
-
 export interface ObjectField<
   Fields extends Record<string, ComponentSchema> = Record<
     string,
@@ -434,7 +422,6 @@ export type ComponentSchema =
       BasicFormField<any, any>,
       { [key: string]: ComponentSchema }
     >
-  | RelationshipField<boolean>
   | ArrayFieldInComponentSchema;
 
 function validateText(
@@ -1302,7 +1289,6 @@ export const fields = {
           formatting?: BlockFormattingConfig | 'inherit';
           dividers?: 'inherit';
           links?: 'inherit';
-          relationships?: 'inherit';
         }
       | {
           kind: 'inline';
@@ -1314,7 +1300,6 @@ export const fields = {
                 softBreaks?: 'inherit';
               };
           links?: 'inherit';
-          relationships?: 'inherit';
         }
   ): ChildField {
     return {
@@ -1337,7 +1322,6 @@ export const fields = {
                     }
                   : options.formatting,
               links: options.links,
-              relationships: options.relationships,
             }
           : {
               kind: 'inline',
@@ -1347,7 +1331,6 @@ export const fields = {
                   ? { inlineMarks: 'inherit', softBreaks: 'inherit' }
                   : options.formatting,
               links: options.links,
-              relationships: options.relationships,
             },
     };
   },
@@ -1401,11 +1384,7 @@ export const fields = {
       }): DocumentElement[] => {
         const markdoc = textDecoder.decode(value.primary);
         const document = fromMarkdoc(Markdoc.parse(markdoc), componentBlocks);
-        const editor = createDocumentEditor(
-          documentFeatures,
-          componentBlocks,
-          {}
-        );
+        const editor = createDocumentEditor(documentFeatures, componentBlocks);
         editor.children = document;
         Editor.normalize(editor, { force: true });
         return deserializeFiles(
@@ -1425,7 +1404,6 @@ export const fields = {
               componentBlocks={componentBlocks}
               documentFeatures={documentFeatures}
               onChange={props.onChange as any}
-              relationships={emptyObject}
               value={props.value as any}
             />
           </FieldPrimitive>
@@ -1579,18 +1557,6 @@ type ConditionalFieldPreviewProps<
   };
 }[keyof Schema['values']];
 
-// this is a separate type so that this is distributive
-type RelationshipDataType<Many extends boolean> = Many extends true
-  ? readonly HydratedRelationshipData[]
-  : HydratedRelationshipData | null;
-
-type RelationshipFieldPreviewProps<Schema extends RelationshipField<boolean>> =
-  {
-    readonly value: RelationshipDataType<Schema['many']>;
-    onChange(relationshipData: RelationshipDataType<Schema['many']>): void;
-    readonly schema: Schema;
-  };
-
 type ArrayFieldPreviewProps<
   Schema extends ArrayField<ComponentSchema>,
   ChildFieldElement
@@ -1621,8 +1587,6 @@ export type GenericPreviewProps<
   ? ObjectFieldPreviewProps<Schema, ChildFieldElement>
   : Schema extends ConditionalField<any, any>
   ? ConditionalFieldPreviewProps<Schema, ChildFieldElement>
-  : Schema extends RelationshipField<any>
-  ? RelationshipFieldPreviewProps<Schema>
   : Schema extends ArrayField<any>
   ? ArrayFieldPreviewProps<Schema, ChildFieldElement>
   : never;
@@ -1656,10 +1620,6 @@ export type InitialOrUpdateValueFromComponentPropField<
         >;
       };
     }[keyof Values]
-  : Schema extends RelationshipField<infer Many>
-  ? Many extends true
-    ? readonly HydratedRelationshipData[]
-    : HydratedRelationshipData | null
   : Schema extends ArrayField<infer ElementField>
   ? readonly {
       key: string | undefined;
@@ -1681,18 +1641,6 @@ type DiscriminantStringToDiscriminantValue<
 export type PreviewPropsForToolbar<Schema extends ComponentSchema> =
   GenericPreviewProps<Schema, undefined>;
 
-export type HydratedRelationshipData = {
-  id: string;
-  label: string;
-  data: Record<string, any>;
-};
-
-export type RelationshipData = {
-  id: string;
-  label: string | undefined;
-  data: Record<string, any> | undefined;
-};
-
 export function component<
   Schema extends {
     [Key in any]: ComponentSchema;
@@ -1760,10 +1708,6 @@ export type ValueForComponentSchema<Schema extends ComponentSchema> =
           readonly value: ValueForComponentSchema<Values[Key]>;
         };
       }[keyof Values]
-    : Schema extends RelationshipField<infer Many>
-    ? Many extends true
-      ? readonly HydratedRelationshipData[]
-      : HydratedRelationshipData | null
     : Schema extends ArrayField<infer ElementField>
     ? readonly ValueForComponentSchema<ElementField>[]
     : never;
@@ -1801,10 +1745,6 @@ export type ValueForReading<Schema extends ComponentSchema> =
           readonly value: ValueForReading<Values[Key]>;
         };
       }[keyof Values]
-    : Schema extends RelationshipField<infer Many>
-    ? Many extends true
-      ? readonly HydratedRelationshipData[]
-      : HydratedRelationshipData | null
     : Schema extends ArrayField<infer ElementField>
     ? readonly ValueForReading<ElementField>[]
     : never;
diff --git a/packages/keystatic/DocumentEditor/component-blocks/field-assertions.ts b/packages/keystatic/DocumentEditor/component-blocks/field-assertions.ts
index cf47ee45..565f8582 100644
--- a/packages/keystatic/DocumentEditor/component-blocks/field-assertions.ts
+++ b/packages/keystatic/DocumentEditor/component-blocks/field-assertions.ts
@@ -1,11 +1,8 @@
 import { ComponentSchema } from './api';
 import { assertNever } from './utils';
 
-export function assertValidComponentSchema(
-  schema: ComponentSchema,
-  lists: ReadonlySet<string>
-) {
-  assertValidComponentSchemaInner(schema, [], [], new Set(), lists);
+export function assertValidComponentSchema(schema: ComponentSchema) {
+  assertValidComponentSchemaInner(schema, [], [], new Set());
 }
 
 // recursive things can exist but they have to either be:
@@ -17,22 +14,11 @@ function assertValidComponentSchemaInner(
   schema: ComponentSchema,
   schemaAncestors: ComponentSchema[],
   propPath: string[],
-  seenProps: Set<ComponentSchema>,
-  lists: ReadonlySet<string>
+  seenProps: Set<ComponentSchema>
 ) {
   if (schema.kind === 'form' || schema.kind === 'child') {
     return;
   }
-  if (schema.kind === 'relationship') {
-    if (lists.has(schema.listKey)) {
-      return;
-    }
-    throw new Error(
-      `The relationship field at "${propPath.join('.')}" has the listKey "${
-        schema.listKey
-      }" but no list named "${schema.listKey}" exists.`
-    );
-  }
   const ancestor = schemaAncestors.indexOf(schema);
   if (ancestor !== -1) {
     throw new Error(
@@ -48,13 +34,7 @@ function assertValidComponentSchemaInner(
   try {
     seenProps.add(schema);
     if (schema.kind === 'array') {
-      assertValidComponentSchemaInner(
-        schema.element,
-        [],
-        propPath,
-        seenProps,
-        lists
-      );
+      assertValidComponentSchemaInner(schema.element, [], propPath, seenProps);
       return;
     }
     if (schema.kind === 'object') {
@@ -72,8 +52,7 @@ function assertValidComponentSchemaInner(
           innerProp,
           schemaAncestors,
           propPath,
-          seenProps,
-          lists
+          seenProps
         );
         propPath.pop();
       }
@@ -97,8 +76,7 @@ function assertValidComponentSchemaInner(
           innerProp,
           key === stringifiedDefaultDiscriminant ? schemaAncestors : [],
           propPath,
-          seenProps,
-          lists
+          seenProps
         );
         propPath.pop();
       }
diff --git a/packages/keystatic/DocumentEditor/component-blocks/form-from-preview.tsx b/packages/keystatic/DocumentEditor/component-blocks/form-from-preview.tsx
index 7deb3485..09ab9250 100644
--- a/packages/keystatic/DocumentEditor/component-blocks/form-from-preview.tsx
+++ b/packages/keystatic/DocumentEditor/component-blocks/form-from-preview.tsx
@@ -35,7 +35,6 @@ import {
   GenericPreviewProps,
   ObjectField,
   PathContextProvider,
-  RelationshipField,
   SlugFieldProvider,
 } from './api';
 import { previewPropsToValue, setValueToPreviewProps } from './get-value';
@@ -340,10 +339,6 @@ function move<T>(
   return copy;
 }
 
-function RelationshipFieldPreview({}: DefaultFieldProps<'relationship'>) {
-  return null;
-}
-
 function FormFieldPreview({
   schema,
   autoFocus,
@@ -435,7 +430,6 @@ export type NonChildFieldComponentSchema =
       BasicFormField<any, any>,
       { [key: string]: ComponentSchema }
     >
-  | RelationshipField<boolean>
   | ArrayField<ComponentSchema>;
 
 function isNonChildFieldPreviewProps(
@@ -446,7 +440,6 @@ function isNonChildFieldPreviewProps(
 
 const fieldRenderers = {
   array: ArrayFieldPreview,
-  relationship: RelationshipFieldPreview,
   child: () => null,
   form: FormFieldPreview,
   object: ObjectFieldPreview,
@@ -514,8 +507,7 @@ export function canFieldBeFocused(schema: ComponentSchema): boolean {
   if (
     schema.kind === 'array' ||
     schema.kind === 'conditional' ||
-    schema.kind === 'form' ||
-    schema.kind === 'relationship'
+    schema.kind === 'form'
   ) {
     return true;
   }
diff --git a/packages/keystatic/DocumentEditor/component-blocks/get-value.ts b/packages/keystatic/DocumentEditor/component-blocks/get-value.ts
index bc5d26d2..601140e3 100644
--- a/packages/keystatic/DocumentEditor/component-blocks/get-value.ts
+++ b/packages/keystatic/DocumentEditor/component-blocks/get-value.ts
@@ -43,9 +43,6 @@ const previewPropsToValueConverter: {
       ])
     );
   },
-  relationship(props) {
-    return props.value;
-  },
 };
 
 export function previewPropsToValue<Schema extends ComponentSchema>(
@@ -92,9 +89,6 @@ const valueToUpdaters: {
       ])
     );
   },
-  relationship(value) {
-    return value;
-  },
 };
 
 function valueToUpdater<Schema extends ComponentSchema>(
@@ -114,7 +108,6 @@ export function setValueToPreviewProps<Schema extends ComponentSchema>(
   }
   if (
     isKind(props, 'form') ||
-    isKind(props, 'relationship') ||
     isKind(props, 'object') ||
     isKind(props, 'array')
   ) {
diff --git a/packages/keystatic/DocumentEditor/component-blocks/initial-values.ts b/packages/keystatic/DocumentEditor/component-blocks/initial-values.ts
index 3a1e6245..49eecf81 100644
--- a/packages/keystatic/DocumentEditor/component-blocks/initial-values.ts
+++ b/packages/keystatic/DocumentEditor/component-blocks/initial-values.ts
@@ -33,8 +33,6 @@ export function getInitialPropsValue(schema: ComponentSchema): any {
       return schema.defaultValue;
     case 'child':
       return null;
-    case 'relationship':
-      return schema.many ? [] : null;
     case 'conditional': {
       const defaultValue = schema.discriminant.defaultValue;
       return {
@@ -65,12 +63,6 @@ export function getInitialPropsValueFromInitializer(
       return initializer === undefined ? schema.defaultValue : initializer;
     case 'child':
       return null;
-    case 'relationship':
-      return initializer === undefined
-        ? schema.many
-          ? []
-          : null
-        : initializer;
     case 'conditional': {
       const defaultValue =
         initializer === undefined
@@ -111,8 +103,6 @@ export function updateValue(
   if (updater === undefined) return currentValue;
 
   switch (schema.kind) {
-    case 'relationship':
-      return updater;
     case 'form':
       return updater;
     case 'child':
diff --git a/packages/keystatic/DocumentEditor/component-blocks/preview-props.tsx b/packages/keystatic/DocumentEditor/component-blocks/preview-props.tsx
index 1bd1bf4e..291ef836 100644
--- a/packages/keystatic/DocumentEditor/component-blocks/preview-props.tsx
+++ b/packages/keystatic/DocumentEditor/component-blocks/preview-props.tsx
@@ -4,9 +4,7 @@ import {
   ConditionalField,
   ValueForComponentSchema,
   FormFieldValue,
-  HydratedRelationshipData,
   ObjectField,
-  RelationshipField,
   GenericPreviewProps,
   BasicFormField,
 } from './api';
@@ -142,14 +140,6 @@ export function createGetPreviewProps<
         ),
       };
     },
-    relationship(schema, onChange) {
-      return (
-        newVal:
-          | HydratedRelationshipData
-          | readonly HydratedRelationshipData[]
-          | null
-      ) => onChange(() => newVal);
-    },
   });
 
   const previewPropsFactories: {
@@ -266,17 +256,6 @@ export function createGetPreviewProps<
       }
       return props;
     },
-    relationship(schema, value, onChange) {
-      const props: GenericPreviewProps<
-        RelationshipField<boolean>,
-        ChildFieldElement
-      > = {
-        value: value,
-        onChange,
-        schema: schema,
-      };
-      return props;
-    },
     conditional(schema, value, memoized, path, getInnerProp) {
       const props: GenericPreviewProps<
         ConditionalField<
diff --git a/packages/keystatic/DocumentEditor/component-blocks/update-element.ts b/packages/keystatic/DocumentEditor/component-blocks/update-element.ts
index af62b9bb..224b340a 100644
--- a/packages/keystatic/DocumentEditor/component-blocks/update-element.ts
+++ b/packages/keystatic/DocumentEditor/component-blocks/update-element.ts
@@ -165,8 +165,6 @@ function findChildPropPathsWithPrevious(
   switch (schema.kind) {
     case 'form':
       return [];
-    case 'relationship':
-      return [];
     case 'child':
       return [{ path: newPath, prevPath, options: schema.options }];
     case 'conditional':
diff --git a/packages/keystatic/DocumentEditor/component-blocks/utils.ts b/packages/keystatic/DocumentEditor/component-blocks/utils.ts
index 6d6e1101..6ac57cb1 100644
--- a/packages/keystatic/DocumentEditor/component-blocks/utils.ts
+++ b/packages/keystatic/DocumentEditor/component-blocks/utils.ts
@@ -16,7 +16,6 @@ export function findChildPropPathsForProp(
 ): PathToChildFieldWithOption[] {
   switch (schema.kind) {
     case 'form':
-    case 'relationship':
       return [];
     case 'child':
       return [{ path: path, options: schema.options }];
@@ -83,7 +82,6 @@ export type DocumentFeaturesForChildField =
       inlineMarks: 'inherit' | DocumentFeatures['formatting']['inlineMarks'];
       documentFeatures: {
         links: boolean;
-        relationships: boolean;
       };
       softBreaks: boolean;
     }
@@ -125,7 +123,6 @@ export function getDocumentFeaturesForChildField(
       inlineMarks,
       documentFeatures: {
         links: options.links === 'inherit',
-        relationships: options.relationships === 'inherit',
       },
       softBreaks: options.formatting?.softBreaks === 'inherit',
     };
@@ -168,7 +165,6 @@ export function getDocumentFeaturesForChildField(
               },
       },
       links: options.links === 'inherit',
-      relationships: options.relationships === 'inherit',
     },
   };
 }
@@ -183,11 +179,7 @@ function getSchemaAtPropPathInner(
   if (path.length === 0) {
     return schema;
   }
-  if (
-    schema.kind === 'child' ||
-    schema.kind === 'form' ||
-    schema.kind === 'relationship'
-  ) {
+  if (schema.kind === 'child' || schema.kind === 'form') {
     return;
   }
   if (schema.kind === 'conditional') {
@@ -244,8 +236,7 @@ export function clientSideValidateProp(
   path: ReadonlyPropPath = []
 ): boolean {
   switch (schema.kind) {
-    case 'child':
-    case 'relationship': {
+    case 'child': {
       return true;
     }
     case 'form': {
@@ -322,11 +313,7 @@ export function getAncestorSchemas(
     } else if (currentProp.kind === 'object') {
       currentValue = (currentValue as any)[key];
       currentProp = currentProp.fields[key];
-    } else if (
-      currentProp.kind === 'child' ||
-      currentProp.kind === 'form' ||
-      currentProp.kind === 'relationship'
-    ) {
+    } else if (currentProp.kind === 'child' || currentProp.kind === 'form') {
       throw new Error(`unexpected prop "${key}"`);
     } else {
       assertNever(currentProp);
@@ -359,11 +346,7 @@ export function traverseProps(
   ) => void,
   path: ReadonlyPropPath = []
 ) {
-  if (
-    schema.kind === 'form' ||
-    schema.kind === 'relationship' ||
-    schema.kind === 'child'
-  ) {
+  if (schema.kind === 'form' || schema.kind === 'child') {
     visitor(schema, value, path);
     return;
   }
@@ -407,11 +390,7 @@ export function transformProps(
   },
   path: ReadonlyPropPath = []
 ): unknown {
-  if (
-    schema.kind === 'form' ||
-    schema.kind === 'relationship' ||
-    schema.kind === 'child'
-  ) {
+  if (schema.kind === 'form' || schema.kind === 'child') {
     if (visitors[schema.kind]) {
       return (visitors[schema.kind] as any)(schema, value, path);
     }
@@ -480,11 +459,7 @@ export async function asyncTransformProps(
   },
   path: ReadonlyPropPath = []
 ): Promise<unknown> {
-  if (
-    schema.kind === 'form' ||
-    schema.kind === 'relationship' ||
-    schema.kind === 'child'
-  ) {
+  if (schema.kind === 'form' || schema.kind === 'child') {
     if (visitors[schema.kind]) {
       return (visitors[schema.kind] as any)(schema, value, path);
     }
@@ -602,13 +577,9 @@ export function replaceValueAtPropPath(
     return newVal;
   }
 
-  // we should never reach here since form, relationship or child fields don't contain other fields
+  // we should never reach here since form or child fields don't contain other fields
   // so the only thing that can happen to them is to be replaced which happens at the start of this function when path.length === 0
-  assert(
-    schema.kind !== 'form' &&
-      schema.kind !== 'relationship' &&
-      schema.kind !== 'child'
-  );
+  assert(schema.kind !== 'form' && schema.kind !== 'child');
 
   assertNever(schema);
 }
diff --git a/packages/keystatic/DocumentEditor/component-blocks/with-component-blocks.tsx b/packages/keystatic/DocumentEditor/component-blocks/with-component-blocks.tsx
index 6aad5fb1..26d5bc47 100644
--- a/packages/keystatic/DocumentEditor/component-blocks/with-component-blocks.tsx
+++ b/packages/keystatic/DocumentEditor/component-blocks/with-component-blocks.tsx
@@ -15,10 +15,9 @@ import { DocumentFeatures } from '../document-features';
 import {
   areArraysEqual,
   normalizeElementBasedOnDocumentFeatures,
-  normalizeInlineBasedOnLinksAndRelationships,
+  normalizeInlineBasedOnLinks as normalizeInlineBasedOnLinks,
   normalizeTextBasedOnInlineMarksAndSoftBreaks,
 } from '../document-features-normalization';
-import { Relationships } from '../relationship';
 import { ChildField, ComponentBlock, ComponentSchema, ArrayField } from './api';
 import {
   assertNever,
@@ -70,8 +69,7 @@ const alreadyNormalizedThings: WeakMap<
 function normalizeNodeWithinComponentProp(
   [node, path]: NodeEntry,
   editor: Editor,
-  fieldOptions: DocumentFeaturesForChildField,
-  relationships: Relationships
+  fieldOptions: DocumentFeaturesForChildField
 ): boolean {
   let alreadyNormalizedNodes = alreadyNormalizedThings.get(fieldOptions);
   if (!alreadyNormalizedNodes) {
@@ -96,8 +94,7 @@ function normalizeNodeWithinComponentProp(
         normalizeNodeWithinComponentProp(
           [node, [...path, i]],
           editor,
-          fieldOptions,
-          relationships
+          fieldOptions
         )
       )
       // .map then .some because we don't want to exit early
@@ -107,16 +104,13 @@ function normalizeNodeWithinComponentProp(
         normalizeElementBasedOnDocumentFeatures(
           [node, path],
           editor,
-          fieldOptions.documentFeatures,
-          relationships
+          fieldOptions.documentFeatures
         ) || childrenHasChanged;
     } else {
-      didNormalization = normalizeInlineBasedOnLinksAndRelationships(
+      didNormalization = normalizeInlineBasedOnLinks(
         [node, path],
         editor,
-        fieldOptions.documentFeatures.links,
-        fieldOptions.documentFeatures.relationships,
-        relationships
+        fieldOptions.documentFeatures.links
       );
     }
   }
@@ -130,7 +124,7 @@ function normalizeNodeWithinComponentProp(
 function canSchemaContainChildField(rootSchema: ComponentSchema) {
   const queue = new Set<ComponentSchema>([rootSchema]);
   for (const schema of queue) {
-    if (schema.kind === 'form' || schema.kind === 'relationship') {
+    if (schema.kind === 'form') {
     } else if (schema.kind === 'child') {
       return true;
     } else if (schema.kind === 'array') {
@@ -156,7 +150,7 @@ function doesSchemaOnlyEverContainASingleChildField(
   const queue = new Set<ComponentSchema>([rootSchema]);
   let hasFoundChildField = false;
   for (const schema of queue) {
-    if (schema.kind === 'form' || schema.kind === 'relationship') {
+    if (schema.kind === 'form') {
     } else if (schema.kind === 'child') {
       if (hasFoundChildField) {
         return false;
@@ -218,7 +212,6 @@ function isEmptyChildFieldNode(
 export function withComponentBlocks(
   blockComponents: Record<string, ComponentBlock | undefined>,
   editorDocumentFeatures: DocumentFeatures,
-  relationships: Relationships,
   editor: Editor
 ): Editor {
   // note that conflicts between the editor document features
@@ -577,8 +570,7 @@ export function withComponentBlocks(
             normalizeNodeWithinComponentProp(
               [childNode, childPath],
               editor,
-              documentFeatures,
-              relationships
+              documentFeatures
             )
           ) {
             return;
@@ -595,11 +587,7 @@ export function withComponentBlocks(
 
 // the only thing that this will fix is a new field being added to an object field, nothing else.
 function addMissingFields(value: unknown, schema: ComponentSchema): unknown {
-  if (
-    schema.kind === 'child' ||
-    schema.kind === 'form' ||
-    schema.kind === 'relationship'
-  ) {
+  if (schema.kind === 'child' || schema.kind === 'form') {
     return value;
   }
   if (schema.kind === 'conditional') {
diff --git a/packages/keystatic/DocumentEditor/document-features-normalization.ts b/packages/keystatic/DocumentEditor/document-features-normalization.ts
index 82087634..ab537466 100644
--- a/packages/keystatic/DocumentEditor/document-features-normalization.ts
+++ b/packages/keystatic/DocumentEditor/document-features-normalization.ts
@@ -1,6 +1,5 @@
 import { Text, Transforms, Element, NodeEntry, Editor, Node } from 'slate';
 import { DocumentFeatures } from './document-features';
-import { Relationships } from './relationship';
 
 export function areArraysEqual(a: readonly unknown[], b: readonly unknown[]) {
   return a.length === b.length && a.every((x, i) => x === b[i]);
@@ -48,15 +47,12 @@ export type DocumentFeaturesForNormalization = Omit<
     DocumentFeatures['formatting'],
     'inlineMarks' | 'softBreaks'
   >;
-  relationships: boolean;
 };
 
-export function normalizeInlineBasedOnLinksAndRelationships(
+export function normalizeInlineBasedOnLinks(
   [node, path]: NodeEntry<Element>,
   editor: Editor,
-  links: boolean,
-  relationshipsEnabled: boolean,
-  relationships: Relationships
+  links: boolean
 ) {
   if (node.type === 'link' && !links) {
     Transforms.insertText(editor, ` (${node.href})`, {
@@ -65,38 +61,13 @@ export function normalizeInlineBasedOnLinksAndRelationships(
     Transforms.unwrapNodes(editor, { at: path });
     return true;
   }
-  if (
-    node.type === 'relationship' &&
-    (!relationshipsEnabled || relationships[node.relationship] === undefined)
-  ) {
-    const data: any = node.data;
-    if (data) {
-      const relationship = relationships[node.relationship];
-      Transforms.insertText(
-        editor,
-        `${data.label || data.id || ''} (${
-          relationship?.label || node.relationship
-        }:${data.id || ''})`,
-        { at: Editor.before(editor, path) }
-      );
-    }
-    Transforms.removeNodes(editor, { at: path });
-    return true;
-  }
   return false;
 }
 
 export function normalizeElementBasedOnDocumentFeatures(
   [node, path]: NodeEntry<Element>,
   editor: Editor,
-  {
-    formatting,
-    dividers,
-    layouts,
-    links,
-    relationships: relationshipsEnabled,
-  }: DocumentFeaturesForNormalization,
-  relationships: Relationships
+  { formatting, dividers, layouts, links }: DocumentFeaturesForNormalization
 ): boolean {
   if (
     (node.type === 'heading' &&
@@ -129,25 +100,14 @@ export function normalizeElementBasedOnDocumentFeatures(
     return true;
   }
 
-  return normalizeInlineBasedOnLinksAndRelationships(
-    [node, path],
-    editor,
-    links,
-    relationshipsEnabled,
-    relationships
-  );
+  return normalizeInlineBasedOnLinks([node, path], editor, links);
 }
 
 export function withDocumentFeaturesNormalization(
   documentFeatures: DocumentFeatures,
-  relationships: Relationships,
   editor: Editor
 ): Editor {
   const { normalizeNode } = editor;
-  const documentFeaturesForNormalization = {
-    ...documentFeatures,
-    relationships: true,
-  };
   editor.normalizeNode = ([node, path]) => {
     if (Text.isText(node)) {
       normalizeTextBasedOnInlineMarksAndSoftBreaks(
@@ -160,8 +120,7 @@ export function withDocumentFeaturesNormalization(
       normalizeElementBasedOnDocumentFeatures(
         [node, path],
         editor,
-        documentFeaturesForNormalization,
-        relationships
+        documentFeatures
       );
     }
     normalizeNode([node, path]);
diff --git a/packages/keystatic/DocumentEditor/index.tsx b/packages/keystatic/DocumentEditor/index.tsx
index 50814a68..8084a765 100644
--- a/packages/keystatic/DocumentEditor/index.tsx
+++ b/packages/keystatic/DocumentEditor/index.tsx
@@ -37,7 +37,6 @@ import { nestList, unnestList, withList } from './lists';
 import { ComponentBlockContext, withComponentBlocks } from './component-blocks';
 import { getPlaceholderTextForPropPath } from './component-blocks/utils';
 import { withBlockquote } from './blockquote';
-import { Relationships, withRelationship } from './relationship';
 import { withDivider } from './divider';
 import { withCodeBlock } from './code-block';
 import { withMarks } from './marks';
@@ -125,8 +124,7 @@ const getKeyDownHandler = (editor: Editor) => (event: KeyboardEvent) => {
 
 export function createDocumentEditor(
   documentFeatures: DocumentFeatures,
-  componentBlocks: Record<string, ComponentBlock>,
-  relationships: Relationships
+  componentBlocks: Record<string, ComponentBlock>
 ) {
   return withPasting(
     withSoftBreaks(
@@ -136,29 +134,25 @@ export function createDocumentEditor(
           componentBlocks,
           withList(
             withHeading(
-              withRelationship(
-                withInsertMenu(
-                  withComponentBlocks(
-                    componentBlocks,
-                    documentFeatures,
-                    relationships,
-                    withParagraphs(
-                      withShortcuts(
-                        withDivider(
-                          withLayouts(
-                            withMarks(
-                              documentFeatures,
-                              componentBlocks,
-                              withCodeBlock(
-                                withBlockMarkdownShortcuts(
-                                  documentFeatures,
-                                  componentBlocks,
-                                  withBlockquote(
-                                    withDocumentFeaturesNormalization(
-                                      documentFeatures,
-                                      relationships,
-                                      withHistory(withReact(createEditor()))
-                                    )
+              withInsertMenu(
+                withComponentBlocks(
+                  componentBlocks,
+                  documentFeatures,
+                  withParagraphs(
+                    withShortcuts(
+                      withDivider(
+                        withLayouts(
+                          withMarks(
+                            documentFeatures,
+                            componentBlocks,
+                            withCodeBlock(
+                              withBlockMarkdownShortcuts(
+                                documentFeatures,
+                                componentBlocks,
+                                withBlockquote(
+                                  withDocumentFeaturesNormalization(
+                                    documentFeatures,
+                                    withHistory(withReact(createEditor()))
                                   )
                                 )
                               )
@@ -182,20 +176,17 @@ export function DocumentEditor({
   onChange,
   value,
   componentBlocks,
-  relationships,
   documentFeatures,
   ...props
 }: {
   onChange: undefined | ((value: Descendant[]) => void);
   value: Descendant[];
   componentBlocks: Record<string, ComponentBlock>;
-  relationships: Relationships;
   documentFeatures: DocumentFeatures;
 } & Omit<EditableProps, 'value' | 'onChange'>) {
   const editor = useMemo(
-    () =>
-      createDocumentEditor(documentFeatures, componentBlocks, relationships),
-    [documentFeatures, componentBlocks, relationships]
+    () => createDocumentEditor(documentFeatures, componentBlocks),
+    [documentFeatures, componentBlocks]
   );
 
   return (
@@ -210,7 +201,6 @@ export function DocumentEditor({
       <DocumentEditorProvider
         componentBlocks={componentBlocks}
         documentFeatures={documentFeatures}
-        relationships={relationships}
         editor={editor}
         value={value}
         onChange={value => {
@@ -265,14 +255,12 @@ export function DocumentEditorProvider({
   value,
   componentBlocks,
   documentFeatures,
-  relationships,
 }: {
   children: ReactNode;
   value: Descendant[];
   onChange: (value: Descendant[]) => void;
   editor: Editor;
   componentBlocks: Record<string, ComponentBlock>;
-  relationships: Relationships;
   documentFeatures: DocumentFeatures;
 }) {
   // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -301,7 +289,6 @@ export function DocumentEditorProvider({
         <ToolbarStateProvider
           componentBlocks={componentBlocks}
           editorDocumentFeatures={documentFeatures}
-          relationships={relationships}
         >
           {children}
         </ToolbarStateProvider>
@@ -463,7 +450,7 @@ while (listDepth--) {
 
 const editableStyles = css(styles);
 
-export type Block = Exclude<Element, { type: 'relationship' | 'link' }>;
+export type Block = Exclude<Element, { type: 'link' }>;
 
 type BlockContainerSchema = {
   kind: 'blocks';
@@ -611,11 +598,7 @@ export function isBlock(node: Descendant): node is Block {
 function withBlocksSchema(editor: Editor): Editor {
   const { normalizeNode } = editor;
   editor.normalizeNode = ([node, path]) => {
-    if (
-      !Text.isText(node) &&
-      node.type !== 'link' &&
-      node.type !== 'relationship'
-    ) {
+    if (!Text.isText(node) && node.type !== 'link') {
       const nodeType = Editor.isEditor(node) ? 'editor' : node.type;
       if (
         typeof nodeType !== 'string' ||
@@ -651,8 +634,7 @@ function withBlocksSchema(editor: Editor): Editor {
             !Editor.isBlock(editor, childNode) ||
             // these checks are implicit in Editor.isBlock
             // but that isn't encoded in types so these will make TS happy
-            childNode.type === 'link' ||
-            childNode.type === 'relationship'
+            childNode.type === 'link'
           ) {
             Transforms.wrapNodes(
               editor,
diff --git a/packages/keystatic/DocumentEditor/insert-menu.tsx b/packages/keystatic/DocumentEditor/insert-menu.tsx
index 3d1262a5..3b72d928 100644
--- a/packages/keystatic/DocumentEditor/insert-menu.tsx
+++ b/packages/keystatic/DocumentEditor/insert-menu.tsx
@@ -17,7 +17,6 @@ import {
 } from './component-blocks';
 import { ComponentBlock } from './component-blocks/api';
 import { insertLayout } from './layouts';
-import { Relationships, useDocumentFieldRelationships } from './relationship';
 import { ToolbarState, useToolbarState } from './toolbar-state';
 import { insertNodesButReplaceIfSelectionIsAtEmptyParagraphOrHeading } from './utils';
 
@@ -29,21 +28,9 @@ type Option = {
 
 function getOptions(
   toolbarState: ToolbarState,
-  componentBlocks: Record<string, ComponentBlock>,
-  relationships: Relationships
+  componentBlocks: Record<string, ComponentBlock>
 ): Option[] {
   const options: (Option | boolean)[] = [
-    ...Object.entries(relationships).map(([relationship, { label }]) => ({
-      label,
-      insert: (editor: Editor) => {
-        Transforms.insertNodes(editor, {
-          type: 'relationship',
-          relationship,
-          data: null,
-          children: [{ text: '' }],
-        });
-      },
-    })),
     ...Object.keys(componentBlocks).map(key => ({
       label: componentBlocks[key].label,
       insert: (editor: Editor) => {
@@ -147,18 +134,10 @@ export function InsertMenu({
   text: Text;
 }) {
   const toolbarState = useToolbarState();
-  const {
-    editor,
-    relationships: { isDisabled: relationshipsDisabled },
-  } = toolbarState;
+  const { editor } = toolbarState;
   const componentBlocks = useContext(ComponentBlockContext);
-  const relationships = useDocumentFieldRelationships();
   const options = matchSorter(
-    getOptions(
-      toolbarState,
-      componentBlocks,
-      relationshipsDisabled ? {} : relationships
-    ),
+    getOptions(toolbarState, componentBlocks),
     text.text.slice(1),
     {
       keys: ['label', 'keywords'],
diff --git a/packages/keystatic/DocumentEditor/pasting/index.ts b/packages/keystatic/DocumentEditor/pasting/index.ts
index e28ec1e7..545b9cce 100644
--- a/packages/keystatic/DocumentEditor/pasting/index.ts
+++ b/packages/keystatic/DocumentEditor/pasting/index.ts
@@ -84,7 +84,7 @@ export function withPasting(editor: Editor): Editor {
           !Editor.isBlock(editor, node.children[0]),
       }) &&
       // and there is only text(potentially with marks) in the selection
-      // no other links or inline relationships
+      // no other links
       Editor.nodes(editor, {
         match: node => Editor.isInline(editor, node),
       }).next().done
diff --git a/packages/keystatic/DocumentEditor/pasting/utils.ts b/packages/keystatic/DocumentEditor/pasting/utils.ts
index e36e7aae..6ea40a87 100644
--- a/packages/keystatic/DocumentEditor/pasting/utils.ts
+++ b/packages/keystatic/DocumentEditor/pasting/utils.ts
@@ -68,7 +68,7 @@ export function forceDisableMarkForChildren<T>(mark: Mark, cb: () => T): T {
 /**
  * This type is more strict than `Element & { type: 'link'; }` because `children`
  * is constrained to only contain Text nodes. This can't be assumed generally around the editor
- * (because of inline relationships or nested links(which are normalized away but the editor needs to not break if it happens))
+ * (because of potentially future inline components or nested links(which are normalized away but the editor needs to not break if it happens))
  * but where this type is used, we're only going to allow links to contain Text and that's important
  * so that we know a block will never be inside an inline because Slate gets unhappy when that happens
  * (really the link inline should probably be a mark rather than an inline,
@@ -76,7 +76,6 @@ export function forceDisableMarkForChildren<T>(mark: Mark, cb: () => T): T {
  * structure which would be such unnecessary breakage)
  */
 type StrictLink = { type: 'link'; href: string; children: Text[] };
-// inline relationships are not here because we never create them from handling a paste from html or markdown
 export type InlineFromExternalPaste = Text | StrictLink;
 
 export function getInlineNodes(
diff --git a/packages/keystatic/DocumentEditor/relationship.tsx b/packages/keystatic/DocumentEditor/relationship.tsx
deleted file mode 100644
index 69821210..00000000
--- a/packages/keystatic/DocumentEditor/relationship.tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-import { createContext, useContext } from 'react';
-import { Editor } from 'slate';
-import { RenderElementProps } from 'slate-react';
-
-export type Relationships = Record<
-  string,
-  {
-    listKey: string;
-    /** GraphQL fields to select when querying the field */
-    selection: string | null;
-    label: string;
-  }
->;
-
-export const DocumentFieldRelationshipsContext = createContext<Relationships>(
-  {}
-);
-
-export function useDocumentFieldRelationships() {
-  return useContext(DocumentFieldRelationshipsContext);
-}
-
-export const DocumentFieldRelationshipsProvider =
-  DocumentFieldRelationshipsContext.Provider;
-
-export function withRelationship(editor: Editor): Editor {
-  const { isVoid, isInline } = editor;
-  editor.isVoid = element => {
-    return element.type === 'relationship' || isVoid(element);
-  };
-  editor.isInline = element => {
-    return element.type === 'relationship' || isInline(element);
-  };
-  return editor;
-}
-
-export function RelationshipElement({}: RenderElementProps & {
-  element: { type: 'relationship' };
-}) {
-  return null;
-}
diff --git a/packages/keystatic/DocumentEditor/render-element.tsx b/packages/keystatic/DocumentEditor/render-element.tsx
index febb97e6..3355b976 100644
--- a/packages/keystatic/DocumentEditor/render-element.tsx
+++ b/packages/keystatic/DocumentEditor/render-element.tsx
@@ -74,8 +74,6 @@ export const renderElement = (props: RenderElementProps) => {
       return <BlockquoteElement {...props} />;
     case 'divider':
       return <DividerElement {...props} />;
-    case 'relationship':
-      return <span {...props.attributes}>{props.children}</span>;
     default:
       let { textAlign } = props.element;
       return (
diff --git a/packages/keystatic/DocumentEditor/slate-types.ts b/packages/keystatic/DocumentEditor/slate-types.ts
index 11858a97..8c87bd27 100644
--- a/packages/keystatic/DocumentEditor/slate-types.ts
+++ b/packages/keystatic/DocumentEditor/slate-types.ts
@@ -10,7 +10,6 @@
 import { BaseEditor, BaseElement, BaseRange } from 'slate';
 import { HistoryEditor } from 'slate-history';
 import { ReactEditor } from 'slate-react';
-import { RelationshipData } from './component-blocks/api';
 import { ReadonlyPropPath } from './component-blocks/utils';
 import { Mark } from './utils';
 
@@ -19,12 +18,6 @@ type Link = {
   href: string;
 };
 
-type Relationship = {
-  type: 'relationship';
-  relationship: string;
-  data: RelationshipData | null;
-};
-
 type Layout = {
   type: 'layout';
   layout: number[];
@@ -76,7 +69,6 @@ type Element = (
   | ComponentProp
   | Paragraph
   | Link
-  | Relationship
   | CodeBlock
 ) &
   BaseElement;
diff --git a/packages/keystatic/DocumentEditor/toolbar-state.tsx b/packages/keystatic/DocumentEditor/toolbar-state.tsx
index 1a53a371..7bc29795 100644
--- a/packages/keystatic/DocumentEditor/toolbar-state.tsx
+++ b/packages/keystatic/DocumentEditor/toolbar-state.tsx
@@ -11,10 +11,7 @@ import {
 } from './component-blocks/utils';
 import { LayoutOptionsProvider } from './layouts';
 import { isListNode } from './lists';
-import {
-  DocumentFieldRelationshipsProvider,
-  Relationships,
-} from './relationship';
+
 import { allMarks, isElementActive, Mark, nodeTypeMatcher } from './utils';
 
 type BasicToolbarItem = { isSelected: boolean; isDisabled: boolean };
@@ -48,7 +45,6 @@ export type ToolbarState = {
   layouts: { isSelected: boolean };
   dividers: { isDisabled: boolean };
   code: BasicToolbarItem;
-  relationships: { isDisabled: boolean };
   editor: Editor;
   editorDocumentFeatures: DocumentFeatures;
 };
@@ -118,7 +114,6 @@ export const createToolbarState = (
         },
         layouts: editorDocumentFeatures.layouts,
         links: true,
-        relationships: true,
       },
       softBreaks: true,
     };
@@ -203,9 +198,6 @@ export const createToolbarState = (
           ? locationDocumentFeatures.documentFeatures.formatting.headingLevels
           : [],
     },
-    relationships: {
-      isDisabled: !locationDocumentFeatures.documentFeatures.relationships,
-    },
     code: {
       isSelected: isElementActive(editor, 'code'),
       isDisabled: !(
@@ -302,30 +294,26 @@ export const ToolbarStateProvider = ({
   children,
   componentBlocks,
   editorDocumentFeatures,
-  relationships,
 }: {
   children: ReactNode;
   componentBlocks: Record<string, ComponentBlock>;
   editorDocumentFeatures: DocumentFeatures;
-  relationships: Relationships;
 }) => {
   const editor = useSlate();
 
   return (
-    <DocumentFieldRelationshipsProvider value={relationships}>
-      <LayoutOptionsProvider value={editorDocumentFeatures.layouts}>
-        <ComponentBlockContext.Provider value={componentBlocks}>
-          <ToolbarStateContext.Provider
-            value={createToolbarState(
-              editor,
-              componentBlocks,
-              editorDocumentFeatures
-            )}
-          >
-            {children}
-          </ToolbarStateContext.Provider>
-        </ComponentBlockContext.Provider>
-      </LayoutOptionsProvider>
-    </DocumentFieldRelationshipsProvider>
+    <LayoutOptionsProvider value={editorDocumentFeatures.layouts}>
+      <ComponentBlockContext.Provider value={componentBlocks}>
+        <ToolbarStateContext.Provider
+          value={createToolbarState(
+            editor,
+            componentBlocks,
+            editorDocumentFeatures
+          )}
+        >
+          {children}
+        </ToolbarStateContext.Provider>
+      </ComponentBlockContext.Provider>
+    </LayoutOptionsProvider>
   );
 };
diff --git a/packages/keystatic/app/required-files.ts b/packages/keystatic/app/required-files.ts
index 5c0fd874..601ffee4 100644
--- a/packages/keystatic/app/required-files.ts
+++ b/packages/keystatic/app/required-files.ts
@@ -24,7 +24,7 @@ function _getRequiredFiles(
   propPath: (string | number)[],
   requiredFiles: RequiredFile[]
 ) {
-  if (schema.kind === 'child' || schema.kind === 'relationship') {
+  if (schema.kind === 'child') {
     return;
   }
   if (schema.kind === 'form') {
diff --git a/packages/keystatic/app/useItemData.ts b/packages/keystatic/app/useItemData.ts
index 886598ff..cf673ca4 100644
--- a/packages/keystatic/app/useItemData.ts
+++ b/packages/keystatic/app/useItemData.ts
@@ -32,7 +32,6 @@ function parseFromValueFile(
   const validated = validateComponentBlockProps(
     schema,
     loaded,
-    {},
     [],
     args.slug
       ? {
diff --git a/packages/keystatic/markdoc/find-children.ts b/packages/keystatic/markdoc/find-children.ts
index cf28f0fc..67a2168b 100644
--- a/packages/keystatic/markdoc/find-children.ts
+++ b/packages/keystatic/markdoc/find-children.ts
@@ -47,7 +47,6 @@ function _findConstantChildFields(
   seenSchemas.add(schema);
   switch (schema.kind) {
     case 'form':
-    case 'relationship':
       return [];
     case 'child':
       return [{ relativePath: path, options: schema.options, kind: 'child' }];
@@ -100,7 +99,6 @@ function couldContainChildField(
   seen.add(schema);
   switch (schema.kind) {
     case 'form':
-    case 'relationship':
       return false;
     case 'child':
       return true;
diff --git a/packages/keystatic/markdoc/to-markdoc.tsx b/packages/keystatic/markdoc/to-markdoc.tsx
index c40815cb..bb8f97b0 100644
--- a/packages/keystatic/markdoc/to-markdoc.tsx
+++ b/packages/keystatic/markdoc/to-markdoc.tsx
@@ -35,14 +35,6 @@ function toMarkdocInline(node: ElementFromValidation): Node | Node[] {
       node.children.flatMap(toMarkdocInline)
     );
   }
-  if (node.type === 'relationship') {
-    return new Ast.Node(
-      'tag',
-      { relationship: node.relationship },
-      [],
-      'relationship'
-    );
-  }
   if (node.type !== undefined) {
     throw new Error(`unexpected inline node type: ${node.type}`);
   }
@@ -77,7 +69,7 @@ function removeUnnecessaryChildFieldValues(
   parent: ComponentSchema | undefined,
   value: unknown
 ): unknown {
-  if (schema.kind === 'relationship' || schema.kind === 'form') {
+  if (schema.kind === 'form') {
     return value;
   }
   if (schema.kind === 'child') {
diff --git a/packages/keystatic/src/reader.ts b/packages/keystatic/src/reader.ts
index 46ecb6c2..3683e987 100644
--- a/packages/keystatic/src/reader.ts
+++ b/packages/keystatic/src/reader.ts
@@ -119,7 +119,6 @@ async function readItem(
   const validated = validateComponentBlockProps(
     schema,
     loaded,
-    {},
     [],
     slugField === undefined
       ? undefined
diff --git a/packages/keystatic/structure-validation.ts b/packages/keystatic/structure-validation.ts
index a9b9e880..af64af78 100644
--- a/packages/keystatic/structure-validation.ts
+++ b/packages/keystatic/structure-validation.ts
@@ -1,6 +1,5 @@
 import * as t from 'io-ts';
 import excess from 'io-ts-excess';
-import { RelationshipData } from './DocumentEditor/component-blocks/api';
 import { Mark } from './DocumentEditor/utils';
 import { isValidURL } from './DocumentEditor/isValidURL';
 // note that this validation isn't about ensuring that a document has nodes in the right positions and things
@@ -26,7 +25,7 @@ export type TextWithMarks = { type?: never; text: string } & {
   [Key in Mark | 'insertMenu']: true | undefined;
 };
 
-export type InlineFromValidation = TextWithMarks | Link | Relationship;
+export type InlineFromValidation = TextWithMarks | Link;
 
 type Link = { type: 'link'; href: string; children: Children };
 
@@ -54,25 +53,7 @@ const link: t.Type<Link> = t.recursion('Link', () =>
   )
 );
 
-type Relationship = {
-  type: 'relationship';
-  relationship: string;
-  data: RelationshipData | null;
-  children: Children;
-};
-
-const relationship: t.Type<Relationship> = t.recursion('Relationship', () =>
-  excess(
-    t.type({
-      type: t.literal('relationship'),
-      relationship: t.string,
-      data: t.union([t.null, relationshipData]),
-      children,
-    })
-  )
-);
-
-const inline = t.union([text, link, relationship]);
+const inline = t.union([text, link]);
 
 type Children = (BlockFromValidation | InlineFromValidation)[];
 
@@ -182,14 +163,6 @@ const paragraph: t.Type<Paragraph> = t.recursion('Paragraph', () =>
   )
 );
 
-const relationshipData: t.Type<RelationshipData> = excess(
-  t.type({
-    id: t.string,
-    label: t.union([t.undefined, t.string]),
-    data: t.union([t.undefined, t.record(t.string, t.any)]),
-  })
-);
-
 type ComponentBlock = {
   type: 'component-block';
   component: string;
@@ -258,10 +231,6 @@ const children: t.Type<Children> = t.recursion('Children', () =>
 
 export const editorCodec = t.array(block);
 
-export function isRelationshipData(val: unknown): val is RelationshipData {
-  return relationshipData.validate(val, [])._tag === 'Right';
-}
-
 export function validateDocumentStructure(
   val: unknown
 ): asserts val is ElementFromValidation[] {
diff --git a/packages/keystatic/utils.tsx b/packages/keystatic/utils.tsx
index d0236078..439374e0 100644
--- a/packages/keystatic/utils.tsx
+++ b/packages/keystatic/utils.tsx
@@ -353,7 +353,7 @@ async function _toFiles(
   }[],
   slugField: string | undefined
 ): Promise<unknown> {
-  if (schema.kind === 'child' || schema.kind === 'relationship') {
+  if (schema.kind === 'child') {
     return value;
   }
   if (schema.kind === 'form') {
diff --git a/packages/keystatic/validate-component-block-props.ts b/packages/keystatic/validate-component-block-props.ts
index 74cee848..ab3e5a97 100644
--- a/packages/keystatic/validate-component-block-props.ts
+++ b/packages/keystatic/validate-component-block-props.ts
@@ -3,8 +3,6 @@ import { isSlugFormField } from './app/utils';
 import { ComponentSchema } from './DocumentEditor/component-blocks/api';
 import { getInitialPropsValue } from './DocumentEditor/component-blocks/initial-values';
 import { ReadonlyPropPath } from './DocumentEditor/component-blocks/utils';
-import { Relationships } from './DocumentEditor/relationship';
-import { isRelationshipData } from './structure-validation';
 
 export class PropValidationError extends Error {
   path: ReadonlyPropPath;
@@ -17,7 +15,6 @@ export class PropValidationError extends Error {
 export function validateComponentBlockProps(
   schema: ComponentSchema,
   value: unknown,
-  relationships: Relationships,
   path: ReadonlyPropPath,
   slugField:
     | {
@@ -66,22 +63,6 @@ export function validateComponentBlockProps(
   if (schema.kind === 'child') {
     return null;
   }
-  if (schema.kind === 'relationship') {
-    if (schema.many) {
-      if (Array.isArray(value) && value.every(isRelationshipData)) {
-        // yes, ts understands this completely correctly, i'm as suprised as you are
-        return value.map(x => ({ id: x.id }));
-      } else {
-        throw new PropValidationError(`Invalid relationship value`, path);
-      }
-    }
-    if (value === null || isRelationshipData(value)) {
-      return value === null ? null : { id: value.id };
-    } else {
-      throw new PropValidationError(`Invalid relationship value`, path);
-    }
-  }
-
   if (schema.kind === 'conditional') {
     if (typeof value !== 'object' || value === null) {
       throw new PropValidationError(
@@ -105,7 +86,6 @@ export function validateComponentBlockProps(
     const discriminantVal = validateComponentBlockProps(
       schema.discriminant,
       discriminant,
-      relationships,
       path.concat('discriminant'),
       slugField
     );
@@ -115,7 +95,6 @@ export function validateComponentBlockProps(
     const conditionalFieldValue = validateComponentBlockProps(
       schema.values[discriminant],
       val,
-      relationships,
       path.concat('value'),
       slugField
     );
@@ -147,7 +126,6 @@ export function validateComponentBlockProps(
       const propVal = validateComponentBlockProps(
         schema.fields[key],
         individualVal,
-        relationships,
         path.concat(key),
         slugField
       );
@@ -168,7 +146,6 @@ export function validateComponentBlockProps(
       return validateComponentBlockProps(
         schema.element,
         innerVal,
-        relationships,
         path.concat(i),
         slugField
       );
diff --git a/packages/keystatic/validation.ts b/packages/keystatic/validation.ts
index e12a8679..21cdb488 100644
--- a/packages/keystatic/validation.ts
+++ b/packages/keystatic/validation.ts
@@ -1,7 +1,6 @@
 import { Text, Editor } from 'slate';
 import { createDocumentEditor } from './DocumentEditor';
 import { ComponentBlock } from './DocumentEditor/component-blocks/api';
-import { Relationships } from './DocumentEditor/relationship';
 import {
   ElementFromValidation,
   TextWithMarks,
@@ -20,8 +19,7 @@ function isText(node: ElementFromValidation): node is TextWithMarks {
 // malicious content being inserted, not valid content
 export function getValidatedNodeWithNormalizedComponentFormProps(
   node: ElementFromValidation,
-  componentBlocks: Record<string, ComponentBlock>,
-  relationships: Relationships
+  componentBlocks: Record<string, ComponentBlock>
 ): ElementFromValidation {
   if (isText(node)) {
     return node;
@@ -34,33 +32,16 @@ export function getValidatedNodeWithNormalizedComponentFormProps(
         props: validateComponentBlockProps(
           { kind: 'object', fields: componentBlock.schema },
           node.props,
-          relationships,
           [],
           undefined
         ),
       };
     }
   }
-
-  if (node.type === 'relationship') {
-    node = {
-      type: 'relationship',
-      data:
-        node.data?.id !== undefined
-          ? { id: node.data.id, data: undefined, label: undefined }
-          : null,
-      relationship: node.relationship,
-      children: node.children,
-    };
-  }
   return {
     ...node,
     children: node.children.map(x =>
-      getValidatedNodeWithNormalizedComponentFormProps(
-        x,
-        componentBlocks,
-        relationships
-      )
+      getValidatedNodeWithNormalizedComponentFormProps(x, componentBlocks)
     ),
   };
 }
@@ -68,22 +49,13 @@ export function getValidatedNodeWithNormalizedComponentFormProps(
 export function validateAndNormalizeDocument(
   value: unknown,
   documentFeatures: DocumentFeatures,
-  componentBlocks: Record<string, ComponentBlock>,
-  relationships: Relationships
+  componentBlocks: Record<string, ComponentBlock>
 ) {
   validateDocumentStructure(value);
   const children = value.map(x =>
-    getValidatedNodeWithNormalizedComponentFormProps(
-      x,
-      componentBlocks,
-      relationships
-    )
-  );
-  const editor = createDocumentEditor(
-    documentFeatures,
-    componentBlocks,
-    relationships
+    getValidatedNodeWithNormalizedComponentFormProps(x, componentBlocks)
   );
+  const editor = createDocumentEditor(documentFeatures, componentBlocks);
   editor.children = children;
   Editor.normalize(editor, { force: true });
   return editor.children;


Test patch:
diff --git a/packages/keystatic/DocumentEditor/component-blocks/document-features-normalization.test.tsx b/packages/keystatic/DocumentEditor/component-blocks/document-features-normalization.test.tsx
index b8f01d53..0b0711df 100644
--- a/packages/keystatic/DocumentEditor/component-blocks/document-features-normalization.test.tsx
+++ b/packages/keystatic/DocumentEditor/component-blocks/document-features-normalization.test.tsx
@@ -113,53 +113,6 @@ const cases: Record<
       <text>some text not in a link (https://example.com) stuff</text>
     ),
   },
-  'relationship allowed': {
-    schema: fields.child({
-      kind: 'block',
-      placeholder: '',
-      relationships: 'inherit',
-    }),
-    children: (
-      <paragraph>
-        <text>some text </text>
-        <relationship
-          relationship="mention"
-          data={{
-            id: '5f6a9d7ec229fe1621532769',
-            label: 'Someone',
-            data: {},
-          }}
-        >
-          <text />
-        </relationship>
-        <text> stuff</text>
-      </paragraph>
-    ),
-  },
-  'relationship not allowed': {
-    schema: fields.child({ kind: 'block', placeholder: '' }),
-    children: (
-      <paragraph>
-        <text>some text </text>
-        <relationship
-          relationship="mention"
-          data={{
-            id: '5f6a9d7ec229fe1621532769',
-            label: 'Someone',
-            data: {},
-          }}
-        >
-          <text />
-        </relationship>
-        <text> stuff</text>
-      </paragraph>
-    ),
-    expectedNormalized: (
-      <paragraph>
-        <text>some text Someone (Mention:5f6a9d7ec229fe1621532769) stuff</text>
-      </paragraph>
-    ),
-  },
   'alignment allowed': {
     schema: fields.child({
       kind: 'block',
@@ -273,13 +226,6 @@ function makeEditorWithChildField(
           schema: { child: childField },
         }),
       },
-      relationships: {
-        mention: {
-          label: 'Mention',
-          listKey: 'User',
-          selection: null,
-        },
-      },
     }
   );
 }
diff --git a/packages/keystatic/DocumentEditor/component-blocks/field-assertions.test.ts b/packages/keystatic/DocumentEditor/component-blocks/field-assertions.test.ts
index 9f9900d6..54a119fe 100644
--- a/packages/keystatic/DocumentEditor/component-blocks/field-assertions.test.ts
+++ b/packages/keystatic/DocumentEditor/component-blocks/field-assertions.test.ts
@@ -20,7 +20,7 @@ const discriminant = fields.checkbox({ label: '' });
 
 test('does not allow circular object', () => {
   expect(() => {
-    assertValidComponentSchema(easilyCircularObject, new Set());
+    assertValidComponentSchema(easilyCircularObject);
   }).toThrowErrorMatchingInlineSnapshot(
     `"The field "object.x" is the same as it's ancestor. Use an array or conditional field for recursive structures."`
   );
@@ -28,7 +28,7 @@ test('does not allow circular object', () => {
 
 test('does not allow a circular object within an array', () => {
   expect(() => {
-    assertValidComponentSchema(fields.array(easilyCircularObject), new Set());
+    assertValidComponentSchema(fields.array(easilyCircularObject));
   }).toThrowErrorMatchingInlineSnapshot(
     `"The field "array.object.x" is the same as it's ancestor. Use an array or conditional field for recursive structures."`
   );
@@ -40,9 +40,7 @@ test('does not allow a circular object within a value for a default discriminant
       fields.conditional(discriminant, {
         true: fields.empty(),
         false: easilyCircularObject,
-      }),
-
-      new Set()
+      })
     );
   }).toThrowErrorMatchingInlineSnapshot(
     `"The field "conditional.false.object.x" is the same as it's ancestor. Use an array or conditional field for recursive structures."`
@@ -55,9 +53,7 @@ test('does not allow a circular object within a value for a non-default discrimi
       fields.conditional(discriminant, {
         true: easilyCircularObject,
         false: fields.empty(),
-      }),
-
-      new Set()
+      })
     );
   }).toThrowErrorMatchingInlineSnapshot(
     `"The field "conditional.true.object.x" is the same as it's ancestor. Use an array or conditional field for recursive structures."`
@@ -75,7 +71,7 @@ test("does allow a circular conditional as long as it's not the default", () =>
     },
     false: fields.empty(),
   });
-  assertValidComponentSchema(conditional, new Set());
+  assertValidComponentSchema(conditional);
 });
 
 test("does not allow a circular conditional if it's the default", () => {
@@ -90,7 +86,7 @@ test("does not allow a circular conditional if it's the default", () => {
     true: fields.empty(),
   });
   expect(() => {
-    assertValidComponentSchema(conditional, new Set());
+    assertValidComponentSchema(conditional);
   }).toThrowErrorMatchingInlineSnapshot(
     `"The field "conditional.false" is the same as it's ancestor. Use an array or conditional field for recursive structures."`
   );
@@ -109,7 +105,7 @@ test("allows circularity if it's stopped by an array field", () => {
       },
     })
   );
-  assertValidComponentSchema(blah, new Set());
+  assertValidComponentSchema(blah);
 });
 
 test('does not allow a field that returns a different field from a getter each time', () => {
@@ -127,7 +123,7 @@ test('does not allow a field that returns a different field from a getter each t
       })
     );
   expect(() => {
-    assertValidComponentSchema(blah(), new Set());
+    assertValidComponentSchema(blah());
   }).toThrowErrorMatchingInlineSnapshot(
     `"Fields on an object field must not change over time but the field at "array.object.blah" changes between accesses"`
   );
@@ -155,6 +151,6 @@ test('exceeds the call stack size for an infinitely recursive field where all fi
     );
   };
   expect(() => {
-    assertValidComponentSchema(blah(), new Set());
+    assertValidComponentSchema(blah());
   }).toThrowErrorMatchingInlineSnapshot(`"Maximum call stack size exceeded"`);
 });
diff --git a/packages/keystatic/DocumentEditor/tests/jsx/impl.ts b/packages/keystatic/DocumentEditor/tests/jsx/impl.ts
index 937b96cf..f9c2e7ad 100644
--- a/packages/keystatic/DocumentEditor/tests/jsx/impl.ts
+++ b/packages/keystatic/DocumentEditor/tests/jsx/impl.ts
@@ -14,7 +14,6 @@ Object.keys(editorSchema).forEach(key => {
 export const __jsx = createHyperscript({
   elements: {
     ...blockTypes,
-    relationship: { type: 'relationship' },
     link: { type: 'link' },
   },
   creators: {},
diff --git a/packages/keystatic/DocumentEditor/tests/jsx/namespace.d.ts b/packages/keystatic/DocumentEditor/tests/jsx/namespace.d.ts
index 26597e4e..d0db2ba3 100644
--- a/packages/keystatic/DocumentEditor/tests/jsx/namespace.d.ts
+++ b/packages/keystatic/DocumentEditor/tests/jsx/namespace.d.ts
@@ -50,16 +50,6 @@ declare namespace __jsx {
         href: string;
         children: Children;
       };
-      relationship: {
-        relationship: string;
-        data: {
-          id: string;
-          label: string;
-          data: {};
-        };
-
-        children: Children;
-      };
     }
     type Element = Node;
     interface ElementAttributesProperty {
diff --git a/packages/keystatic/DocumentEditor/tests/utils.tsx b/packages/keystatic/DocumentEditor/tests/utils.tsx
index 3a1aae69..4cc4c261 100644
--- a/packages/keystatic/DocumentEditor/tests/utils.tsx
+++ b/packages/keystatic/DocumentEditor/tests/utils.tsx
@@ -8,7 +8,6 @@ import { Slate } from 'slate-react';
 import { createDocumentEditor, DocumentEditorEditable } from '..';
 import { ComponentBlock } from '../component-blocks/api';
 import { DocumentFeatures } from '../document-features';
-import { Relationships } from '../relationship';
 import { createToolbarState, ToolbarStateProvider } from '../toolbar-state';
 import { validateDocumentStructure } from '../../structure-validation';
 import { validateAndNormalizeDocument } from '../../validation';
@@ -80,16 +79,14 @@ expect.extend({
     validateAndNormalizeDocument(
       received.children,
       receivedConfig.documentFeatures,
-      receivedConfig.componentBlocks,
-      receivedConfig.relationships
+      receivedConfig.componentBlocks
     );
 
     const expectedConfig = (expected as any).__config;
     validateAndNormalizeDocument(
       expected.children,
       expectedConfig.documentFeatures,
-      expectedConfig.componentBlocks,
-      expectedConfig.relationships
+      expectedConfig.componentBlocks
     );
 
     const pass =
@@ -167,12 +164,10 @@ function EditorComp({
   editor,
   componentBlocks,
   documentFeatures,
-  relationships,
 }: {
   editor: Editor;
   componentBlocks: Record<string, ComponentBlock>;
   documentFeatures: DocumentFeatures;
-  relationships: Relationships;
 }) {
   const [val, setVal] = useState(editor.children);
   return (
@@ -181,7 +176,6 @@ function EditorComp({
         <ToolbarStateProvider
           componentBlocks={componentBlocks}
           editorDocumentFeatures={documentFeatures}
-          relationships={relationships}
         >
           <DocumentEditorEditable
             // the default implementation of scrollSelectionIntoView crashes in JSDOM for some reason
@@ -200,13 +194,11 @@ export const makeEditor = (
     documentFeatures = defaultDocumentFeatures,
     componentBlocks = {},
     normalization = 'disallow-non-normalized',
-    relationships = {},
     skipRenderingDOM,
   }: {
     documentFeatures?: DocumentFeatures;
     componentBlocks?: Record<string, ComponentBlock>;
     normalization?: 'disallow-non-normalized' | 'normalize' | 'skip';
-    relationships?: Relationships;
     isShiftPressedRef?: MutableRefObject<boolean>;
     skipRenderingDOM?: boolean;
   } = {}
@@ -216,8 +208,7 @@ export const makeEditor = (
   }
   let editor = createDocumentEditor(
     documentFeatures,
-    componentBlocks,
-    relationships
+    componentBlocks
   ) as Editor & {
     container?: HTMLElement;
   };
@@ -225,7 +216,6 @@ export const makeEditor = (
   (editor as any).__config = {
     documentFeatures,
     componentBlocks,
-    relationships,
   };
 
   validateDocumentStructure(editor.children);
@@ -260,7 +250,6 @@ export const makeEditor = (
       documentFeatures,
       isShiftPressedRef: { current: false },
       normalization: 'skip',
-      relationships,
       skipRenderingDOM: true,
     });
   if (normalization === 'normalize') {
@@ -281,7 +270,6 @@ export const makeEditor = (
         editor={editor}
         componentBlocks={componentBlocks}
         documentFeatures={documentFeatures}
-        relationships={relationships}
       />
     );
     editor.container = container;
@@ -358,8 +346,7 @@ function nodeToReactElement(
     validateAndNormalizeDocument(
       node.children,
       config.documentFeatures,
-      config.componentBlocks,
-      config.relationships
+      config.componentBlocks
     );
     const marks = Editor.marks(node);
 
diff --git a/packages/keystatic/markdoc/find-children.test.ts b/packages/keystatic/markdoc/find-children.test.ts
index c82fe906..d63056f2 100644
--- a/packages/keystatic/markdoc/find-children.test.ts
+++ b/packages/keystatic/markdoc/find-children.test.ts
@@ -16,7 +16,6 @@ test('one child field', () => {
         "kind": "block",
         "links": undefined,
         "placeholder": "a",
-        "relationships": undefined,
       },
       "relativePath": [
         "a",
@@ -40,7 +39,6 @@ test('nested one child field', () => {
         "kind": "block",
         "links": undefined,
         "placeholder": "a",
-        "relationships": undefined,
       },
       "relativePath": [
         "a",
@@ -112,7 +110,6 @@ test('array', () => {
           "kind": "inline",
           "links": undefined,
           "placeholder": "Content",
-          "relationships": undefined,
         },
         "relativePath": [
           "content",
@@ -129,7 +126,6 @@ test('array', () => {
                 "kind": "inline",
                 "links": undefined,
                 "placeholder": "Content",
-                "relationships": undefined,
               },
             },
             "heading": {