decaporg / decap-cms

A Git-based CMS for Static Site Generators
https://decapcms.org
MIT License
17.79k stars 3.03k forks source link

MDX Support Requirements #2064

Open erquhart opened 5 years ago

erquhart commented 5 years ago

This issue serves as a collaborative space for outlining requirements for MDX support in Netlify CMS.

Related to #1776.

Motivation

Netlify CMS works alongside static site generators (SSG's), which cater heavily toward Markdown as a content format. MDX is a superset of Markdown that uses JSX components for dynamic content, an approach already made viable by JavaScript based SSG's like Gatsby and Next.js, and validated in many real world projects. Netlify CMS should serve as an enabler for MDX projects with non-technical content editors.

Design

MDX authoring will happen in the existing markdown widget. The widget has "Rich Text" and "Markdown" modes, the former providing a WYSIWYG experience and the latter providing direct editing of the underlying markdown. Both modes edit the same value and output Markdown. The Markdown editor also provides an extensible list of Editor Components, which are used to output shortcodes. This same mechanism should be used for JSX component authoring.

Imports

MDX support must be handled at the format level. Netlify CMS currently supports data files, such as JSON and YAML, as well as Markdown with frontmatter. MDX introduces import statements before the frontmatter that Netlify CMS will have to parse, or at a minimum, ignore.

Exports

If possible, export statements should be ignored through reads and writes, but not used in any way, nor made editable.

Registering Components

We can allow components to be registered using the existing registerEditorComponent method. A simplistic approach would be to accept a unique name and the related React component, and then match via tag name. This is similar to what Gatsby is doing. The downside to this approach is that component names must be unique across a project. We could use configuration to limit this to a per-collection requirement, but I suspect uniqueness across the project may be tolerable for our initial support model.

Potential registration example for this approach:

import CMS from 'netlify-cms'
import YouTube from 'src/components/YouTube'

{
  componentName: "YouTube",
  label: "YouTube",
  fields: [{ name: 'id', label: 'Youtube Video ID', widget: 'string' }],
  component: YouTube,
}

Previewing Components

The component passed in at registration would be used in the preview pane (and potentially in the control pane in the future!), but we can make getting started even simpler by not requiring a component at all. If an MDX component does not have a registered preview component, we can list the name and properties of the component in the preview pane instead as a basic representation of the content.

Babel standalone will be required for rendering components parsed from an MDX document, which I've found to work well for CMS preview purposes, even in terms of performance. Haven't tested on very large docs, though.

Document handling

The Netlify CMS Markdown widget uses a document model that's powered by Unified via a heavily customized Remark/Rehype implementation for WYSIWYG markdown editing with live HTML previews. The UI is built with Slate, with the widget transforming MDAST to Slate's AST and back as necessary. MDX is now a part of Unified, and work is underway to support an MDXAST format that is highly compatible with the MDAST and HAST formats already in use in Netlify CMS.

The packages in the MDX repository should provide what we need to parse to/from MDAST, but more research is required to fully determine the path forward.

adrw commented 5 years ago

Are there any plans for an intermediate step in having mdx files appear in Netlify CMS and simply fallback to support as it exists for md files?

Adding a mdx fallback to md would as a stop gap measure allow editing in Netlify CMS of content and regular Markdown stylings that exist in mdx files. This would provide basic editing functionality much sooner instead of blocking on releasing any mdx editing functionality until full import/export and full mdx support is added (which understandably will take much longer to implement).

erquhart commented 5 years ago

Not sure why I never responded to this - you can already have any file you want show up in the CMS via [extension and format] config settings.

lasersox commented 5 years ago

Thanks!

On Tue, Sep 3, 2019 at 10:21 AM Shawn Erquhart notifications@github.com wrote:

Not sure why I never responded to this - you can already have any file you want show up in the CMS via [extension and format] config settings.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/netlify/netlify-cms/issues/2064?email_source=notifications&email_token=AAAEWR7SJZZ66XXFO4C4M43QH2MLHA5CNFSM4GUPQPQ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5Y523A#issuecomment-527555948, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAEWR7TUDYTC6AKVYDF66DQH2MLHANCNFSM4GUPQPQQ .

micahgodbolt commented 4 years ago
extension: "mdx"
format: "frontmatter"

works for folders....but doesn't appear to work for files

loke-dev commented 4 years ago

I'm trying to get mdx to work for single files, but just like @micahgodbolt said, it doesn't work. Can't use folder either becuase it is index.mdx

donaldboulton commented 4 years ago

There is a Gatsby Starter that is using Netify CMS and MDX at Gatsby Starter Netlify CMS - MDX, so renvrant figured it out.

erquhart commented 4 years ago

If you just want to write raw mdx, that already works. Previews might not, can’t recall.

Sent with GitHawk

mikestopcontinues commented 4 years ago

I didn't see any direct mention of handling non-body fields in an mdx doc. I think you should be able to use export vars instead of frontmatter when using mdx, as that's the canonical mdx pattern.