craft.js: Conditionally wrapping `Element` causes an error, works without wrapping

I’m trying to conditionally render either an Elemen or the actual dom node based on whether or not I’m editing or exporting. Currently my own solution for exporting the nodes to Next.js or HTML, otherwise it requires two separate copies of the same node, one for editing and one for exporting which I’m trying to avoid.

Copying the same Element implementation you have, I try to hand down the exact same information.

let isExporting = false;

export type Element<T extends React.ElementType> = {
  id?: NodeId;
  is?: T;
  custom?: Record<string, any>;
  children?: React.ReactNode;
  canvas?: boolean;
} & React.ComponentProps<T>;

export function Element<T extends React.ElementType>({
  id,
  children,
  ...props
}: Element<T>) {

  // const testElement1 = React.createElement(
  //   CraftElement,
  //   { id, is: "div", custom: props.custom, canvas: props.canvas },
  //   children
  // );

  const testElement2 = (
    <CraftElement id={id} {...props}>
      {children}
    </CraftElement>
  );

  return (isExporting
    ? (React.createElement(props.is, props.elementProps, children))
    : testElement2);

  // return (
  //   <CraftElement id={id} {...props}>
  //     {children}
  //   </CraftElement>
  // );
}

This actually works, but only as long as there are no children Elements, as having children causes

Error: Invariant failed: The component type specified for this node (Element) does not exist in the resolver

I’ve tried various implementations, all failing: directly supply the props, change the is to div to see if it’s a scope issue, etc.

Is there any way I can get this to work?

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Comments: 16 (4 by maintainers)

Most upvoted comments

Hi I can confirm this error is still happening. It happens to me when I have < element >{children}< /element >

I fixed this by ensuring my Container was listed in the resolver list.

<Editor resolver={{Button, Text, Container}}> .... </Editor>

The reproduce code sandbox I created above (https://codesandbox.io/s/craftjs-cond-element-9szcsl) clearly has Container in the Resolver list and yet the issue persists.

I fixed this by ensuring my Container was listed in the resolver list.

<Editor resolver={{Button, Text, Container}}> .... </Editor>

why would this resolve the issue

Weird, would it be possible for you to create a codesandbox reproducing the behaviour?