karolis-sh / gatsby-mdx

Utilities to work with MDX and netlify-cms in Gatsby sites
MIT License
60 stars 9 forks source link

mdx widget invalid mdx #51

Closed Bulletninja closed 5 years ago

Bulletninja commented 5 years ago

I created a simple components in src/components/MyComponent but i get this error:

Invalid MDX:
ReferenceError: MyComponent is not defined

when i try to use it like this:

import MyComponent from '../../src/components/MyComponent';
<MyComponent />

My config.yml:

backend:
  name: git-gateway
  branch: master

media_folder: "static/media"
public_folder: "/media"

collections:
  - name: "posts"
    label: "Posts"
    folder: "content/posts"
    create: true
    slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
    fields:
      - {label: "Template", name: "template", widget: "hidden", default: "post"}
      - {label: "Title", name: "title", widget: "string"}
      - {label: "Slug", name: "slug", widget: "string"}
      - {label: "Draft", name: "draft", widget: "boolean", default: true}
      - {label: "Publish Date", name: "date", widget: "datetime"}
      - {label: "Description", name: "description", widget: "text"}
      - {label: "Category", name: "category", widget: "string"}
      - {label: "Body", name: "body", widget: "markdown"}
      - {label: "Tags", name: "tags", widget: "list"}

  - name: "pages"
    label: "Pages"
    folder: "content/pages"
    extension: "mdx"
    format: "frontmatter"
    widget: "mdx"
    create: true
    slug: "{{slug}}"
    fields:
      - {label: "Template", name: "template", widget: "hidden", default: "page"}
      - {label: "Title", name: "title", widget: "string"}
      - {label: "Slug", name: "slug", widget: "string"}
      - {label: "Draft", name: "draft", widget: "boolean", default: true}
      - {label: "Body", name: "body", widget: "mdx"}

and my cms config:

import CMS from 'netlify-cms';
import { MdxControl, MdxPreview } from 'netlify-cms-widget-mdx';
import PagePreview from './preview-templates/page-preview';
import PostPreview from './preview-templates/post-preview';

CMS.registerPreviewTemplate('pages', PagePreview);
CMS.registerPreviewTemplate('posts', PostPreview);
CMS.registerWidget('mdx', MdxControl, MdxPreview);

Am i missing something? 🤔

PS: After clearing cache and rerunning things i get:

Invalid MDX:
CompileError: Transforming import is not implemented. Use `transforms: { moduleImport: false }` to skip transformation and disable this error. (1:0)
1 : import MyComponent from '../../src/components/MyComponent';
karolis-sh commented 5 years ago

The @mdx-js/runtime by default doesn't work with imports, thats why you need some setup in order for them to work with this widget.

https://github.com/karolis-sh/gatsby-mdx/tree/master/packages/netlify-cms-widget-mdx#install

Something like this should work:

import CMS from 'netlify-cms';
import { MdxControl, setupPreview } from 'netlify-cms-widget-mdx';
import PagePreview from './preview-templates/page-preview';
import PostPreview from './preview-templates/post-preview';
import MyComponent from '../components/MyComponent';

CMS.registerPreviewTemplate('pages', PagePreview);
CMS.registerPreviewTemplate('posts', PostPreview);
CMS.registerWidget('mdx', MdxControl, setupPreview({
  allowedImports: {
    '../../src/components/MyComponent': {
      ImportDefault: MyComponent,
    }
  }
}));

As this is rather verbose I suggest having an index.js file in your src/components that re-exports every component that you would like to use in mdx file:

import { MyComponent } from '../../src/components';
<MyComponent />
import CMS from 'netlify-cms';
import { MdxControl, setupPreview } from 'netlify-cms-widget-mdx';
import PagePreview from './preview-templates/page-preview';
import PostPreview from './preview-templates/post-preview';
import * as Components from '../components';

CMS.registerPreviewTemplate('pages', PagePreview);
CMS.registerPreviewTemplate('posts', PostPreview);
CMS.registerWidget('mdx', MdxControl, setupPreview({
  allowedImports: {
    '../../src/components/MyComponent': {
      Import: Components,
    }
  }
}));