Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fence blocks can result in invalid nodes missing a name that breaks react rendering #306

Closed
addisonj opened this issue Dec 23, 2022 · 2 comments
Labels
bug Something isn't working

Comments

@addisonj
Copy link
Contributor

addisonj commented Dec 23, 2022

What happened?

When using a custom Fence node with a definition of:

{
 ...
 fence: {
    render: 'Fence',
    attributes: {
      language: { type: String },
      process: { type: Boolean, render: false, default: true },
    }
  },
  ...
}

And a (simplified) component being passed like:

  const r = Markdoc.renderers.react(markdoc.content, React, {
    components: (name) => {
      return componentLibrary[name]
    },
  })

Where component library has a component like:

export const componentLibrary = {
  ...
  Fence: Fence,
  ...

Can result an AST representation like:

{
  "$$mdtype": "Node",
  "errors": [], 
  "lines": [
    21, 
    35  
  ],  
  "inline": false,
  "attributes": {
    "content": "int main() {...}\n",
    "language": "cpp"
  },  
  "children": [
    {   
      "$$mdtype": "Node",
      "errors": [], 
      "lines": [default
        21, 
        35  
      ],  
      "inline": true,
      "attributes": {
        "content": "int main() {...}\n"
      },
      "children": [], 
      "type": "text",
      "annotations": [], 
      "location": {
        "file": "4 - Connect/2 - Clients & Tools/3 - Client - C++.md",
        "start": {
          "line": 21
        },  
        "end": {
          "line": 35
        }   
      }   
    }   
  ],  
  "type": "fence",
  "annotations": [], 
  "location": {
    "file": "4 - Connect/2 - Clients & Tools/3 - Client - C++.md",
    "start": {
      "line": 21
    },  
    "end": {
      "line": 35
    }   
  }
}

And an output node of

{
  "$$mdtype": "Tag",
  "attributes": {
    "language": "cpp"
  },  
  "children": [
    "int main() {...}\n"
  ]
}

This results in an error in an error:

Error occurred prerendering page "/docs/connect-cpp". Read more: https://nextjs.org/docs/messages/prerender-error
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

I have traced this down to https://github.com/markdoc/markdoc/blob/main/src/renderers/react/react.ts#L53

Where the name property is undefined, which results in us being unable to resolve to the proper component.

I have been unable to see where this happens.

If I take the default transform function for fence node and add it to my fence defintion, this fixes the error (but breaks the rendering of my component)

To reproduce

I don't have a minimal reproduce yet....

Version

0.2.1

Additional context

This is using a custom integration, but it is a pretty straight forward in it's usage of transforms and react

@addisonj addisonj added the bug Something isn't working label Dec 23, 2022
@addisonj
Copy link
Contributor Author

I have found the cause of this issue:

My markdown config object was, in some cases, being modified and malformed during processing.

Specifically, I am re-using some of the functionality of @markdoc/next.js which expects the render field to be a function to render a component instead of a string, so my config object was getting modified.

While this bug was my own, it was difficult to track down and I think it might be nice for Markdoc to do some more input validation.

Specifically, I think validating the markdoc config object might make it easier to catch bugs in usage as it is a non-trivial object to build.

I will keep this open to let you decide how you want to handle that.

@mfix-stripe
Copy link
Contributor

Hey @addisonj — makes sense. You can validate the Markdoc config object by using the Config type exported from @markdoc/markdoc.

Going to close this issue since you resolved your case, but @rpaul-stripe we should consider potentially adding some warning message to the React renderer when in development.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants