mirror of
https://github.com/mdx-js/mdx.git
synced 2024-08-16 18:30:27 +03:00
New and improved docs, with a website (#198)
* Begin adding more involved docs * Begin docs site * Bump deps * Continue with possible docs structure * Improve docs * Add md and jsx syntax links * Add live editor for MDX in docs * Ensure classname is set * Add more docs and a deploy script * Tweak docs index page wording * Add an advanced section * Change order of pages * Improve component docs * Add logo * Begin adding now config for docs deploy * Fix now config * Remove travis based now build * Add dockerfile for site building * Don't run prepare scripts * mdx docs and pointer to gatsby-mdx (#200) * Reorganize docs * Fix typo * Clean up app file * More docs organization * Add WIP labels to WIP sections * Add sync api docs * Add MDX deck link * Implement option to opt out of export wrapper (#209) In certain cases, like mdx-js/runtime or mdx-deck we want to avoid the wrapping export default so that it doesn't need to be manually stripped off. * v0.15.0-2 * Update readme to reflect new docs * Add license link * Add link to vid in docs
This commit is contained in:
parent
e61b567ac0
commit
d4154b8c4a
9
Dockerfile
Normal file
9
Dockerfile
Normal file
@ -0,0 +1,9 @@
|
||||
FROM mhart/alpine-node
|
||||
|
||||
WORKDIR /usr/src
|
||||
|
||||
COPY package.json .
|
||||
RUN npm i --ignore-scripts
|
||||
|
||||
COPY . .
|
||||
RUN npm run docs:build && mv dist /public
|
82
docs/_app.js
Normal file
82
docs/_app.js
Normal file
@ -0,0 +1,82 @@
|
||||
import React from 'react'
|
||||
import RebassMDX from '@rebass/mdx'
|
||||
import createScope from '@rebass/markdown'
|
||||
import * as Rebass from 'rebass'
|
||||
import sortBy from 'lodash.sortby'
|
||||
import { SidebarLayout, ScopeProvider } from '@compositor/x0/components'
|
||||
|
||||
import { LiveEditor, Logo } from './_ui'
|
||||
|
||||
const scope = { ...createScope(), ...Rebass, code: LiveEditor, pre: ({ children }) => children }
|
||||
|
||||
const navOrder = [
|
||||
'index',
|
||||
'syntax',
|
||||
'getting-started',
|
||||
'webpack',
|
||||
'parcel',
|
||||
'next',
|
||||
'create-react-app',
|
||||
'gatsby',
|
||||
'x0',
|
||||
'typescript',
|
||||
'plugins',
|
||||
'advanced',
|
||||
'ast',
|
||||
'components',
|
||||
'writing-a-plugin',
|
||||
'custom-loader',
|
||||
'specification',
|
||||
'sync-api',
|
||||
'runtime',
|
||||
'contributing',
|
||||
'projects',
|
||||
'about'
|
||||
]
|
||||
|
||||
const pageNames = {
|
||||
index: 'Introduction',
|
||||
next: 'Next.js',
|
||||
ast: 'AST',
|
||||
projects: 'Projects Using MDX',
|
||||
'getting-started': 'Getting Started',
|
||||
'create-react-app': 'Create React App',
|
||||
'writing-a-plugin': 'Writing a Plugin',
|
||||
'sync-api': 'Sync API'
|
||||
}
|
||||
|
||||
const sortRoutes = routes => [
|
||||
...sortBy([...routes], a => {
|
||||
const i = navOrder.indexOf(a.name)
|
||||
return i < 0 ? Infinity : i
|
||||
})
|
||||
].map(route => {
|
||||
if (!pageNames[route.name]) return route
|
||||
return {
|
||||
...route,
|
||||
name: pageNames[route.name]
|
||||
}
|
||||
})
|
||||
|
||||
export default class App extends React.Component {
|
||||
static defaultProps = {
|
||||
title: 'MDX'
|
||||
}
|
||||
|
||||
render () {
|
||||
const { routes } = this.props
|
||||
const nav = sortRoutes(routes)
|
||||
|
||||
return (
|
||||
<RebassMDX>
|
||||
<ScopeProvider scope={scope}>
|
||||
<SidebarLayout
|
||||
{...this.props}
|
||||
logo={<Logo />}
|
||||
routes={nav}
|
||||
/>
|
||||
</ScopeProvider>
|
||||
</RebassMDX>
|
||||
)
|
||||
}
|
||||
}
|
38
docs/_ui.js
Normal file
38
docs/_ui.js
Normal file
@ -0,0 +1,38 @@
|
||||
import React from 'react'
|
||||
import { Pre, Box, Border } from 'rebass'
|
||||
import { LiveEditor as Editor, LivePreview } from '@compositor/x0/components'
|
||||
|
||||
export const Logo = () => <img src="https://mdx-logo.now.sh" width="70" />
|
||||
|
||||
export const LiveEditor = props => {
|
||||
const lang = (props.className || '').replace(/^language\-/, '')
|
||||
const type = lang.charAt(0)
|
||||
const code = React.Children.toArray(props.children).join('\n')
|
||||
|
||||
switch (type) {
|
||||
case '.':
|
||||
return (
|
||||
<Editor
|
||||
mdx={lang === '.mdx'}
|
||||
code={code}
|
||||
/>
|
||||
)
|
||||
case '!':
|
||||
return (
|
||||
<LivePreview
|
||||
mdx={lang === '!mdx'}
|
||||
code={code}
|
||||
/>
|
||||
)
|
||||
default:
|
||||
return (
|
||||
<Pre
|
||||
p={3}
|
||||
mt={4}
|
||||
mb={4}
|
||||
bg='gray'
|
||||
children={props.children}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
54
docs/about.md
Normal file
54
docs/about.md
Normal file
@ -0,0 +1,54 @@
|
||||
import { Avatar } from 'rebass'
|
||||
|
||||
# About
|
||||
|
||||
MDX is based on the [original `.mdx` proposal](https://spectrum.chat/thread/1021be59-2738-4511-aceb-c66921050b9a) by Guillermo Rauch ([@rauchg](https://twitter.com/rauchg)).
|
||||
|
||||
## Design
|
||||
|
||||
[Logo designs](https://github.com/mdx-js/design) were created by [Evil Rabbit](https://twitter.com/evilrabbit_) of [ZEIT](https://zeit.co).
|
||||
|
||||
[See logo resources](https://github.com/mdx-js/design)
|
||||
|
||||
## Authors
|
||||
|
||||
- [John Otander](https://johno.com) ([@4lpine](https://twitter.com/4lpine)) – [Compositor](https://compositor.io) + [Clearbit](https://clearbit.com)
|
||||
- Tim Neutkens ([@timneutkens](https://github.com/timneutkens)) – [ZEIT](https://zeit.co)
|
||||
- [Guillermo Rauch](https://rauchg.com) ([@rauchg](https://twitter.com/rauchg)) – [ZEIT](https://zeit.co)
|
||||
- [Brent Jackson](https://jxnblk.com) ([@jxnblk](https://twitter.com/jxnblk)) – [Compositor](https://compositor.io)
|
||||
|
||||
## Related
|
||||
|
||||
The following projects, languages, and articles helped to shape MDX either in implementation or inspiration.
|
||||
|
||||
### Syntax
|
||||
|
||||
These projects define the syntax which MDX blends together (MD and JSX).
|
||||
|
||||
- [Markdown](https://daringfireball.net/projects/markdown/syntax)
|
||||
- [JSX](https://reactjs.org/docs/introducing-jsx.html)
|
||||
- [React](https://reactjs.org/)
|
||||
|
||||
### Parsing and implementation
|
||||
|
||||
- [Remark](http://remark.js.org)
|
||||
- [Unified](https://github.com/unifiedjs/unified)
|
||||
- [Webpack](https://webpack.js.org)
|
||||
- [Parcel](https://parceljs.com)
|
||||
|
||||
### Libraries
|
||||
|
||||
- [MDXC](https://github.com/jamesknelson/mdxc)
|
||||
- [Markdown Component Loader](https://github.com/ticky/markdown-component-loader)
|
||||
- [markdown-in-js](https://github.com/threepointone/markdown-in-js)
|
||||
- [remark-jsx](https://github.com/fazouane-marouane/remark-jsx)
|
||||
- [remark-react](https://github.com/mapbox/remark-react)
|
||||
|
||||
### Other
|
||||
|
||||
- [IA Markdown Content Blocks](https://github.com/iainc/Markdown-Content-Blocks)
|
||||
- [Idyll: Markup language for interactive documents](https://idyll-lang.org)
|
||||
|
||||
### Is your work missing?
|
||||
|
||||
If you have related work or prior art we've failed to reference, please open a PR!
|
118
docs/advanced/ast.md
Normal file
118
docs/advanced/ast.md
Normal file
@ -0,0 +1,118 @@
|
||||
# AST
|
||||
|
||||
The majority of the MDXAST specification is defined by [MDAST][].
|
||||
MDXAST is a superset of MDAST, with three additional node types:
|
||||
|
||||
- `jsx` (in place of `html`)
|
||||
- `import`
|
||||
- `export`
|
||||
|
||||
It's also important to note that an MDX document that contains no JSX or imports is a valid MDAST.
|
||||
|
||||
### Differences to MDAST
|
||||
|
||||
The `import` type is used to provide the necessary block elements to the Remark HTML block parser and for the execution context/implementation.
|
||||
For example, a webpack [loader][] might want to transform an MDX import by appending those imports.
|
||||
|
||||
An `export` is used to emit data from MDX, similarly to traditional markdown frontmatter.
|
||||
|
||||
The `jsx` node would most likely be passed to Babel to create functions.
|
||||
|
||||
This will also differ a bit in parsing because the remark parser is built to handle particular HTML element types, whereas JSX support will require the ability to parse any tag, and those that self close.
|
||||
|
||||
The `jsx`, `import`, and `export` node types are defined below.
|
||||
|
||||
#### JSX
|
||||
|
||||
The `JSX` ([`ElementNode`](#elementnode)) which contains embedded JSX as a string and `children` ([`ElementNode`](#elementnode)).
|
||||
|
||||
```idl
|
||||
interface JSX <: Element {
|
||||
type: "jsx";
|
||||
value: "string";
|
||||
children: [ElementNode]
|
||||
}
|
||||
```
|
||||
|
||||
For example, the following MDX:
|
||||
|
||||
```jsx
|
||||
<Heading hi='there'>
|
||||
Hello, world!
|
||||
</Heading>
|
||||
```
|
||||
|
||||
Yields:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "jsx",
|
||||
"value": "<Heading hi='there'>\n Hello, world!\n</Heading>"
|
||||
}
|
||||
```
|
||||
|
||||
#### Import
|
||||
|
||||
The `import` ([`Textnode`](#textnode)) contains the raw import as a string.
|
||||
|
||||
```idl
|
||||
interface JSX <: Text {
|
||||
type: "import";
|
||||
}
|
||||
```
|
||||
|
||||
For example, the following MDX:
|
||||
|
||||
```md
|
||||
import Video from '../components/Video'
|
||||
```
|
||||
|
||||
Yields:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "import",
|
||||
"value": "import Video from '../components/Video'"
|
||||
}
|
||||
```
|
||||
|
||||
#### Export
|
||||
|
||||
The `export` ([`Textnode`](#textnode)) contains the raw export as a string.
|
||||
|
||||
```idl
|
||||
interface JSX <: Text {
|
||||
type: "export";
|
||||
}
|
||||
```
|
||||
|
||||
For example, the following MDX:
|
||||
|
||||
```md
|
||||
export { foo: 'bar' }
|
||||
```
|
||||
|
||||
Yields:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "export",
|
||||
"value": "export { foo: 'bar' }"
|
||||
}
|
||||
```
|
||||
|
||||
## MDXHAST
|
||||
|
||||
The majority of the MDXHAST specification is defined by [HAST][].
|
||||
MDXHAST is a superset of HAST, with four additional node types:
|
||||
|
||||
- `jsx`
|
||||
- `import`
|
||||
- `export`
|
||||
- `inlineCode`
|
||||
|
||||
It's also important to note that an MDX document that contains no JSX or imports results in a valid HAST.
|
||||
|
||||
[MDAST]: https://github.com/syntax-tree/mdast
|
||||
[HAST]: https://github.com/syntax-tree/hast
|
||||
[loader]: https://github.com/mdx-js/mdx/tree/master/packages/loader
|
41
docs/advanced/components.md
Normal file
41
docs/advanced/components.md
Normal file
@ -0,0 +1,41 @@
|
||||
# Components
|
||||
|
||||
The MDX core library accepts a string and exports a JSX string.
|
||||
|
||||
## MDXTag
|
||||
|
||||
MDXTag is an internal component that MDX uses to map components to an HTML element based on the Markdown syntax.
|
||||
Consider the following MDX:
|
||||
|
||||
```
|
||||
import MyComponent from './my-component'
|
||||
|
||||
# Title
|
||||
|
||||
<MyComponent />
|
||||
|
||||
Lorem ipsum dolor sit amet.
|
||||
```
|
||||
|
||||
MDX core turns that text into the following JSX to be consumed by your app:
|
||||
|
||||
```jsx
|
||||
import React from 'react'
|
||||
import { MDXTag } from '@mdx-js/tag'
|
||||
import MyComponent from './my-component'
|
||||
|
||||
export default ({ components }) => (
|
||||
<MDXTag name="wrapper" components={components}>
|
||||
<MDXTag name="h1" components={components}>
|
||||
Title
|
||||
</MDXTag>
|
||||
<MyComponent />
|
||||
<MDXTag name="p" components={components}>
|
||||
Lorem ipsum dolor sit amet.
|
||||
</MDXTag>
|
||||
</MDXTag>
|
||||
)
|
||||
```
|
||||
|
||||
If the component mapping contains a `p` key, that will be used for "Lorem ipsum dolor sit amet.", otherwise a standard `p` tag is rendered (`<p>Lorem ipsum dolor sit amet.</p>`).
|
||||
This is what allows you to pull in existing components to style your MDX documents.
|
20
docs/advanced/contributing.md
Normal file
20
docs/advanced/contributing.md
Normal file
@ -0,0 +1,20 @@
|
||||
# Contributing
|
||||
|
||||
:pray: Thanks in advance for your contribution!
|
||||
|
||||
To get started, after cloning the repo:
|
||||
|
||||
```
|
||||
npm i
|
||||
npm t
|
||||
```
|
||||
|
||||
## Project structure
|
||||
|
||||
MDX is a monorepo that uses [lerna][].
|
||||
|
||||
- All packages are found in `./packages`
|
||||
- All documentation is found in `./docs` and can be viewed with `npm run docs -- -o`
|
||||
- There's an `./examples` directory where examples for different tools and frameworks
|
||||
|
||||
[lerna]: https://lernajs.io
|
7
docs/advanced/custom-loader.md
Normal file
7
docs/advanced/custom-loader.md
Normal file
@ -0,0 +1,7 @@
|
||||
import { Message } from 'rebass'
|
||||
|
||||
# Custom loader
|
||||
|
||||
<Message>
|
||||
This docs page is a WIP
|
||||
</Message>
|
7
docs/advanced/index.md
Normal file
7
docs/advanced/index.md
Normal file
@ -0,0 +1,7 @@
|
||||
import { Message } from 'rebass'
|
||||
|
||||
# Advanced
|
||||
|
||||
<Message>
|
||||
This docs page is a WIP
|
||||
</Message>
|
3
docs/advanced/runtime.md
Normal file
3
docs/advanced/runtime.md
Normal file
@ -0,0 +1,3 @@
|
||||
import Doc from '../../packages/runtime/readme.md'
|
||||
|
||||
<Doc />
|
11
docs/advanced/specification.md
Normal file
11
docs/advanced/specification.md
Normal file
@ -0,0 +1,11 @@
|
||||
# MDX Specification
|
||||
|
||||
MDX includes a [specification][spec] to define the syntax and transpilation.
|
||||
This can be leveraged by code formatters, linters, and implementations in other languages created by the community.
|
||||
It's based on the [remark][remark]/[unist][unist] ecosystem to ensure robust parsing and the ability to leverage plugins from within your MDX.
|
||||
|
||||
[See the specification][spec]
|
||||
|
||||
[spec]: https://github.com/mdx-js/specification
|
||||
[remark]: https://github.com/remarkjs
|
||||
[unified]: https://github.com/unifiedjs
|
23
docs/advanced/sync-api.md
Normal file
23
docs/advanced/sync-api.md
Normal file
@ -0,0 +1,23 @@
|
||||
import { Message } from 'rebass'
|
||||
|
||||
# Sync API
|
||||
|
||||
MDX processes everything asynchronously by default.
|
||||
In certain cases this behavior might not be desirable.
|
||||
|
||||
If you're using the MDX library directly, you might want to process an MDX string synchronously.
|
||||
It's important to note that if you have any async plugins, they will be ignored.
|
||||
|
||||
```js
|
||||
const fs = require('fs')
|
||||
const mdx = require('@mdx-js/mdx')
|
||||
|
||||
const mdxText = fs.readFileSynx('hello.mdx', 'utf8')
|
||||
|
||||
const jsx = mdx.sync(mdxText)
|
||||
```
|
||||
|
||||
MDX's [runtime][] package has [example][] usage.
|
||||
|
||||
[runtime]: https://github.com/mdx-js/mdx/tree/master/packages/runtime
|
||||
[example]: https://github.com/mdx-js/mdx/blob/d5a5189e715dc28370de13f6cc0fd18a06f0f122/packages/runtime/src/index.js#L16-L18
|
7
docs/advanced/writing-a-plugin.md
Normal file
7
docs/advanced/writing-a-plugin.md
Normal file
@ -0,0 +1,7 @@
|
||||
import { Message } from 'rebass'
|
||||
|
||||
# Writing a plugin
|
||||
|
||||
<Message>
|
||||
This docs page is a WIP
|
||||
</Message>
|
41
docs/getting-started/create-react-app.md
Normal file
41
docs/getting-started/create-react-app.md
Normal file
@ -0,0 +1,41 @@
|
||||
import { Message } from 'rebass'
|
||||
|
||||
# Create React App
|
||||
|
||||
<Message>
|
||||
This docs page is a WIP
|
||||
</Message>
|
||||
|
||||
With Create React App you will need to use [`create-react-app-rewired`][cra-rewired] and add a `config-overrides.js`.
|
||||
|
||||
```js
|
||||
const { getBabelLoader } = require('react-app-rewired')
|
||||
module.exports = (config, env) => {
|
||||
const babelLoader = getBabelLoader(config.module.rules)
|
||||
config.module.rules.map(rule => {
|
||||
if (typeof rule.test !== 'undefined' || typeof rule.oneOf === 'undefined') {
|
||||
return rule
|
||||
}
|
||||
|
||||
rule.oneOf.unshift({
|
||||
test: /\.mdx$/,
|
||||
use: [
|
||||
{
|
||||
loader: babelLoader.loader,
|
||||
options: babelLoader.options
|
||||
},
|
||||
'@mdx-js/loader'
|
||||
]
|
||||
})
|
||||
|
||||
return rule
|
||||
})
|
||||
return config
|
||||
}
|
||||
```
|
||||
|
||||
[See the full example][cra-example]
|
||||
|
||||
[cra]: https://github.com/facebook/create-react-app
|
||||
[cra-rewired]: https://github.com/timarney/react-app-rewired
|
||||
[cra-example]: https://github.com/mdx-js/mdx/tree/master/examples/create-react-app
|
35
docs/getting-started/gatsby.md
Normal file
35
docs/getting-started/gatsby.md
Normal file
@ -0,0 +1,35 @@
|
||||
# Gatsby
|
||||
|
||||
In order to use MDX with [Gatsby][gatsby] you can use the [gatsby-mdx][] package.
|
||||
|
||||
First scaffold a new Gatsby 2.0 or greater site and install the `gatsby-mdx` plugin.
|
||||
|
||||
```shell
|
||||
gatsby new gatsby-site https://github.com/gatsbyjs/gatsby-starter-default#v2
|
||||
cd gatsby-site
|
||||
yarn add gatsby-mdx @mdx-js/mdx
|
||||
```
|
||||
|
||||
Then add `gatsby-mdx` to your `gatsby-config.js` in the `plugins` section.
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
siteMetadata: {
|
||||
title: `My Ambitious Project`
|
||||
},
|
||||
plugins: [`gatsby-mdx`]
|
||||
};
|
||||
```
|
||||
|
||||
Finally, add an `.mdx` file in the `src/pages` directory. It "Just Works".
|
||||
|
||||
```
|
||||
# My first MDX Page
|
||||
|
||||
some awesome content
|
||||
```
|
||||
|
||||
For more documentation on programmatically creating pages with Gatsby, see the [gatsby-mdx docs][gatsby-mdx]
|
||||
|
||||
[gatsby]: https://gatsbyjs.org
|
||||
[gatsby-mdx]: https://github.com/ChristopherBiscardi/gatsby-mdx
|
84
docs/getting-started/index.md
Normal file
84
docs/getting-started/index.md
Normal file
@ -0,0 +1,84 @@
|
||||
import { Text } from 'rebass'
|
||||
|
||||
# Getting Started
|
||||
|
||||
To get started quickly with an example project you can use `npm init`.
|
||||
It will scaffold out a [Next.js][next] app with MDX configured.
|
||||
|
||||
```
|
||||
npm init mdx
|
||||
```
|
||||
|
||||
<Text color="darkgray" mt={-3} mb={4}>
|
||||
Note: MDX requires a version of node that is >= v8.5 and React 16.0+
|
||||
</Text>
|
||||
|
||||
## Components
|
||||
|
||||
You can pass in components for any HTML element that Markdown compiles to.
|
||||
This allows you to use your existing components and even CSS-in-JS like `styled-components`.
|
||||
|
||||
```jsx
|
||||
import React from 'react'
|
||||
import Hello from '../hello.md'
|
||||
|
||||
import {
|
||||
Text,
|
||||
Heading,
|
||||
Code,
|
||||
InlineCode
|
||||
} from '../ui'
|
||||
|
||||
export default () =>
|
||||
<Hello
|
||||
components={{
|
||||
h1: Heading,
|
||||
p: Text,
|
||||
code: Code,
|
||||
inlineCode: InlineCode
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
With the above, the Heading component will be rendered for any h1, Text for p tags, and so on.
|
||||
|
||||
In addition to HTML elements, there's an `inlineCode`.
|
||||
This is what remark uses for code elements within paragraphs, tables, etc.
|
||||
|
||||
## MDXProvider
|
||||
|
||||
If you're using an app layout that wraps your JSX, you can use the `MDXProvider` to only pass your components in one place:
|
||||
|
||||
```jsx
|
||||
import React from 'react'
|
||||
import { MDXProvider } from '@mdx-js/tag'
|
||||
|
||||
import * as components from './markdown-components'
|
||||
|
||||
export default props =>
|
||||
<MDXProvider components={components}>
|
||||
<main {...props} />
|
||||
</MDXProvider>
|
||||
```
|
||||
|
||||
This allows you to remove duplicated component imports and passing.
|
||||
It will typically go in layout files.
|
||||
|
||||
#### How does it work?
|
||||
|
||||
MDXProvider uses React [context][] to provide the component mapping to MDXTag.
|
||||
MDXTag knows to use these components when determining which to render.
|
||||
|
||||
## Projects, libraries and frameworks
|
||||
|
||||
If you're already working with a particular tool, you can try out MDX with the following commands:
|
||||
|
||||
- `npm init mdx` [`webpack`](./webpack)
|
||||
- `npm init mdx` [`parcel`](./parcel)
|
||||
- `npm init mdx` [`next`](./next)
|
||||
- `npm init mdx` [`create-react-app`](./create-react-app)
|
||||
- `npm init mdx` [`gatsby`](./gatsby)
|
||||
- `npm init mdx` [`x0`](./x0)
|
||||
|
||||
[next]: https://github.com/zeit/next.js
|
||||
[context]: https://reactjs.org/docs/context.html
|
31
docs/getting-started/next.md
Normal file
31
docs/getting-started/next.md
Normal file
@ -0,0 +1,31 @@
|
||||
# Next.js
|
||||
|
||||
Next.js provides an [official plugin][next-plugin] to simplify MDX importing into your project.
|
||||
|
||||
```
|
||||
npm install --save-dev @zeit/next-mdx
|
||||
```
|
||||
|
||||
To configure MDX, add the following to your `next.config.js`:
|
||||
|
||||
```js
|
||||
const withMDX = require('@zeit/next-mdx')()
|
||||
|
||||
module.exports = withMDX()
|
||||
```
|
||||
|
||||
### Use MDX for `.md` files
|
||||
|
||||
The Next.js MDX plugin allows for you to also use MDX parsing for `.md` files:
|
||||
|
||||
```js
|
||||
const withMDX = require('@zeit/next-mdx')({
|
||||
extension: /\.mdx?$/
|
||||
})
|
||||
|
||||
module.exports = withMDX({
|
||||
pageExtensions: ['js', 'jsx', 'md', 'mdx']
|
||||
})
|
||||
```
|
||||
|
||||
[next-plugin]: https://github.com/zeit/next-plugins/tree/master/packages/next-mdx
|
26
docs/getting-started/parcel.md
Normal file
26
docs/getting-started/parcel.md
Normal file
@ -0,0 +1,26 @@
|
||||
import { Message } from 'rebass'
|
||||
|
||||
# Parcel
|
||||
|
||||
<Message>
|
||||
This docs page is a WIP
|
||||
</Message>
|
||||
|
||||
You'll need to install the `@mdx-js/parcel-plugin-mdx` plugin to transpile MDX.
|
||||
|
||||
```js
|
||||
{
|
||||
"scripts": {
|
||||
"start": "parcel index.html --no-cache"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "16.4.1",
|
||||
"react-dom": "16.4.1",
|
||||
"@mdx-js/tag": "@mdx-js/tag"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@mdx-js/parcel-plugin-mdx": "@mdx-js/parcel-plugin-mdx",
|
||||
"parcel-bundler": "1.9.0"
|
||||
}
|
||||
}
|
||||
```
|
11
docs/getting-started/typescript.md
Normal file
11
docs/getting-started/typescript.md
Normal file
@ -0,0 +1,11 @@
|
||||
# TypeScript
|
||||
|
||||
If you're getting errors from TypeScript related to imports with an `*.mdx` extension, create an `mdx.d.ts` file in your types directory and include inside your `tsconfig.json`
|
||||
|
||||
```
|
||||
// types/mdx.d.ts
|
||||
declare module '*.mdx' {
|
||||
let MDXComponent: (props) => JSX.Element;
|
||||
export default MDXComponent;
|
||||
}
|
||||
```
|
26
docs/getting-started/webpack.md
Normal file
26
docs/getting-started/webpack.md
Normal file
@ -0,0 +1,26 @@
|
||||
import { Message } from 'rebass'
|
||||
|
||||
# Webpack
|
||||
|
||||
<Message>
|
||||
This docs page is a WIP
|
||||
</Message>
|
||||
|
||||
## Basic Setup
|
||||
|
||||
MDX provides a loader that needs to be used in tandem with the [babel-loader][babel-loader].
|
||||
|
||||
For webpack projects you can define the following `webpack.config.js`:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.mdx?$/,
|
||||
use: ['babel-loader', '@mdx-js/loader']
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
27
docs/getting-started/x0.md
Normal file
27
docs/getting-started/x0.md
Normal file
@ -0,0 +1,27 @@
|
||||
import { Message } from 'rebass'
|
||||
|
||||
# x0
|
||||
|
||||
<Message>
|
||||
This docs page is a WIP
|
||||
</Message>
|
||||
|
||||
[x0][] supports MDX files with either `.md` or `.mdx` file extensions out of the box, but you will need to use the component provider in `_app.js`. Here's an example using [Rebass][rebass] components:
|
||||
|
||||
```jsx
|
||||
import React from 'react'
|
||||
import * as Rebass from 'rebass'
|
||||
import createScope from '@rebass/markdown'
|
||||
import { ScopeProvider } from '@compositor/x0/components'
|
||||
|
||||
export default ({ route, routes, ...props }) => (
|
||||
<ScopeProvider scope={{ ...Rebass, ...createScope() }}>
|
||||
<Rebass.Provider>
|
||||
<Rebass.Box p={[2, 4, 4]} {...props} />
|
||||
</Rebass.Provider>
|
||||
</ScopeProvider>
|
||||
)
|
||||
```
|
||||
|
||||
[x0]: https://compositor.io/x0
|
||||
[rebass]: https://jxnblk.com/rebass
|
56
docs/index.md
Normal file
56
docs/index.md
Normal file
@ -0,0 +1,56 @@
|
||||
import { Border, Blockquote, BlockLink } from 'rebass'
|
||||
|
||||
# MDX
|
||||
|
||||
MDX enables you to seamlessly use JSX in your Markdown documents.
|
||||
This makes writing long-form content with components a blast.
|
||||
|
||||
__:heart: Powerful__: MDX makes it effortless to import and render components in your React/JSX-based projects.
|
||||
|
||||
__:computer: Component-based__: Use existing JSX components inside your MDX, and import MDX files as plain components.
|
||||
|
||||
__:fire: Blazingly blazing fast__: MDX has no runtime, all compilation occurs during the build stage.
|
||||
|
||||
> “It's extremely useful for using design system components to render markdown
|
||||
and weaving interactive components in with existing markdown.”
|
||||
>
|
||||
> — [@chrisbiscardi](https://twitter.com/chrisbiscardi/status/1022304288326864896)
|
||||
|
||||
## Why?
|
||||
|
||||
Before MDX, some of the benefits of writing Markdown were lost when integrating with JSX.
|
||||
Implementations were often template string-based which required lots of escaping and cumbersome syntax.
|
||||
|
||||
MDX seeks to make writing with Markdown _and_ JSX simpler while being more expressive.
|
||||
The possibilities are endless when you combine components (that can even be dynamic or load data) with the simplicity of Markdown for long-form content.
|
||||
|
||||
## Features
|
||||
|
||||
- Fast
|
||||
- No runtime compilation
|
||||
- [Pluggable][remark-plugins]
|
||||
- Element to React component mapping
|
||||
- React component `import`/`export`
|
||||
- Customizable layouts
|
||||
- Webpack loader
|
||||
- Parcel plugin
|
||||
- Next.js plugin
|
||||
- Gatsby plugin
|
||||
|
||||
> [Watch some of these features in action](https://www.youtube.com/watch?v=d2sQiI5NFAM&list=PLV5CVI1eNcJgCrPH_e6d57KRUTiDZgs0u)
|
||||
|
||||
## Try it
|
||||
|
||||
```.mdx
|
||||
# Hello, world!
|
||||
|
||||
Here's an example of the [Rebass][] Donut rendered inside an MDX document.
|
||||
|
||||
<Donut value={2/3} />
|
||||
|
||||
[Rebass]: https://jxnblk.com/rebass
|
||||
```
|
||||
|
||||
[md]: http://commonmark.org/
|
||||
[jsx]: https://facebook.github.io/jsx/
|
||||
[remark-plugins]: https://github.com/remarkjs/remark/blob/master/doc/plugins.md
|
82
docs/plugins.md
Normal file
82
docs/plugins.md
Normal file
@ -0,0 +1,82 @@
|
||||
# Plugins
|
||||
|
||||
Since MDX uses the [remark][]/[rehype][] ecosystems, you can use plugins to modify the AST at different stages of the transpilation process.
|
||||
|
||||
## Transpilation
|
||||
|
||||
The MDX transpilation flow consists of six steps, ultimately resulting in JSX that can be used in React/Preact/etc.
|
||||
|
||||
1. __Parse__: Text => MDAST
|
||||
1. __Transpile__: MDAST => MDXAST
|
||||
1. __Transform__: MDX/Remark plugins applied to AST
|
||||
1. __Transpile__: MDXAST => MDXHAST
|
||||
1. __Transform__: Hyperscript plugins applied to AST
|
||||
1. __Transpile__: MDXHAST => JSX
|
||||
|
||||
### Options
|
||||
|
||||
Name | Type | Required | Description
|
||||
---- | ---- | -------- | -----------
|
||||
`mdPlugins` | Array[] | `false` | Array of remark plugins to manipulate the MDAST
|
||||
`hastPlugins` | Array[] | `false` | Array of rehype plugins to manipulate the MDXHAST
|
||||
|
||||
#### Specifying plugins
|
||||
|
||||
Plugins need to be passed to MDX core library, this is often as options to your loader:
|
||||
|
||||
```js
|
||||
const images = require('remark-images')
|
||||
const emoji = require('remark-emoji')
|
||||
|
||||
module.exports = {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.mdx?$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader'
|
||||
},
|
||||
{
|
||||
loader: '@mdx-js/loader',
|
||||
options: {
|
||||
mdPlugins: [images, emoji]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Though if you're using MDX directly, they can be passed like so:
|
||||
|
||||
```js
|
||||
const fs = require('fs')
|
||||
const mdx = require('@mdx-js/mdx')
|
||||
const images = require('remark-images')
|
||||
const emoji = require('remark-emoji')
|
||||
|
||||
const mdxText = fs.readFileSync('hello.mdx', 'utf8')
|
||||
const jsx = mdx.sync(mdxText, {
|
||||
mdPlugins: [images, emoji]
|
||||
})
|
||||
```
|
||||
|
||||
#### Plugin options
|
||||
|
||||
If a plugin needs specific options, use the `[plugin, pluginOptions]` syntax.
|
||||
|
||||
```js
|
||||
mdx.sync(mdxText, {
|
||||
mdPlugins: [
|
||||
images,
|
||||
[emoji, { padSpaceAfter: true }]
|
||||
})
|
||||
```
|
||||
|
||||
The following example ensures that `padSpaceAfter` is only passed as options to the `emoji` plugin.
|
||||
|
||||
[remark]: https://github.com/remarkjs/remark
|
||||
[rehype]: https://github.com/rehypejs/rehype
|
16
docs/projects.md
Normal file
16
docs/projects.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Projects using MDX
|
||||
|
||||
- [ok-mdx][]: Browser-based MDX editor
|
||||
- [docz][]: Documentation framework
|
||||
- [mdx-deck][]: MDX-based presentation decks
|
||||
|
||||
## Sites using MDX
|
||||
|
||||
- [ZEIT Docs][zeit-docs]
|
||||
- [Compositor][compositor]
|
||||
|
||||
[ok-mdx]: https://github.com/jxnblk/ok-mdx
|
||||
[mdx-deck]: https://github.com/jxnblk/mdx-deck
|
||||
[docz]: https://www.docz.site/
|
||||
[zeit-docs]: https://github.com/zeit/docs
|
||||
[compositor]: https://compositor.io
|
125
docs/syntax.md
Normal file
125
docs/syntax.md
Normal file
@ -0,0 +1,125 @@
|
||||
# Syntax
|
||||
|
||||
MDX syntax can be boiled down to being JSX in Markdown.
|
||||
It's a superset of Markdown syntax that also support importing, exporting, and JSX blocks.
|
||||
|
||||
### Markdown
|
||||
|
||||
Standard [Markdown syntax][md] is supported.
|
||||
|
||||
### JSX
|
||||
|
||||
[JSX syntax][jsx] is fully supported, JSX blocks are opened by starting a line with the `<` character.
|
||||
|
||||
```jsx
|
||||
<Box>
|
||||
<Heading>Here's a JSX block</Heading>
|
||||
<Text>It's pretty neat</Text>
|
||||
</Box>
|
||||
```
|
||||
|
||||
### Imports
|
||||
|
||||
Imports can be used to [import][] components into the scope and later rendered:
|
||||
|
||||
```jsx
|
||||
import Graph from './components/graph'
|
||||
|
||||
## Here's a graph
|
||||
|
||||
<Graph />
|
||||
```
|
||||
|
||||
You can also import data that you want to display in a JSX block:
|
||||
|
||||
```jsx
|
||||
import { colors } from './theme'
|
||||
import Palette from './components/palette'
|
||||
|
||||
# Colors
|
||||
|
||||
<Palette colors={colors} />
|
||||
```
|
||||
|
||||
#### Markdown file transclusion
|
||||
|
||||
You can [transclude][] Markdown files by importing one `.md` or `.mdx` file into another:
|
||||
|
||||
```jsx
|
||||
import License from './license.md'
|
||||
import Contributing from './docs/contributing.md'
|
||||
|
||||
# Hello, world!
|
||||
|
||||
<License />
|
||||
|
||||
---
|
||||
|
||||
<Contributing />
|
||||
```
|
||||
|
||||
### Exports
|
||||
|
||||
You can use exports to export metadata like layout or authors.
|
||||
It's a mechanism for an imported MDX file to communicate with its parent.
|
||||
It works similarly to frontmatter, but uses ES2015 syntax.
|
||||
|
||||
```js
|
||||
// posts/post.mdx
|
||||
import { fred, sue } from '../data/authors'
|
||||
import Layout from '../components/blog-layout'
|
||||
|
||||
export const meta = {
|
||||
authors: [fred, sue],
|
||||
layout: Layout
|
||||
}
|
||||
|
||||
# Post about MDX
|
||||
|
||||
MDX is a JSX in Markdown loader, parser, and renderer for ambitious projects.
|
||||
```
|
||||
|
||||
```jsx
|
||||
// index.js
|
||||
import React from 'react'
|
||||
import Mdx, { meta } from 'posts/post.mdx'
|
||||
|
||||
const { authors, layout } = meta
|
||||
|
||||
export default () => (
|
||||
<layout>
|
||||
<Mdx />
|
||||
By: {authors.map(author => author.name)}
|
||||
</layout>
|
||||
)
|
||||
```
|
||||
|
||||
#### `export default`
|
||||
|
||||
The ES default [export][] is used to provide a layout component which will wrap the transpiled JSX.
|
||||
|
||||
You can export it as a function:
|
||||
|
||||
```jsx
|
||||
import Layout from './Layout'
|
||||
|
||||
export default ({ children }) => <Layout some='metadata' >{children}</Layout>
|
||||
|
||||
# Hello, world!
|
||||
```
|
||||
|
||||
Or directly as a component:
|
||||
|
||||
```jsx
|
||||
import Layout from './Layout'
|
||||
|
||||
export default Layout
|
||||
|
||||
# Hello, world!
|
||||
```
|
||||
|
||||
[md]: https://daringfireball.net/projects/markdown/syntax
|
||||
[jsx]: https://reactjs.org/docs/introducing-jsx.html
|
||||
[import]: https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/import
|
||||
[export]: https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export
|
||||
[transclude]: https://en.wikipedia.org/wiki/Transclusion
|
6
now.json
Normal file
6
now.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "mdx",
|
||||
"alias": "mdxjs.com",
|
||||
"public": true,
|
||||
"type": "static"
|
||||
}
|
15
package.json
15
package.json
@ -2,6 +2,9 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"bootstrap": "lerna bootstrap",
|
||||
"docs": "x0 docs",
|
||||
"docs:build": "x0 build docs",
|
||||
"docs:deploy": "npm run docs:build && now dist",
|
||||
"test": "lerna run test",
|
||||
"format": "prettier --no-semi --single-quote --write '{examples,packages}/**/*.js'",
|
||||
"prepare": "lerna bootstrap && lerna link --force-local"
|
||||
@ -9,7 +12,15 @@
|
||||
"repository": "mdx-js/mdx",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"lerna": "^2.5.1",
|
||||
"prettier": "^1.11.1"
|
||||
"@compositor/x0": "^6.0.3",
|
||||
"lerna": "^2.11.0",
|
||||
"prettier": "^1.13.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"@rebass/mdx": "^1.0.0-1",
|
||||
"styled-components": "^3.3.3"
|
||||
},
|
||||
"x0": {
|
||||
"title": "MDX"
|
||||
}
|
||||
}
|
||||
|
374
readme.md
374
readme.md
@ -3,360 +3,52 @@
|
||||
[![Build Status](https://travis-ci.org/mdx-js/mdx.svg?branch=master)](https://travis-ci.org/mdx-js/mdx)
|
||||
[![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/mdx)
|
||||
|
||||
MDX is a JSX in Markdown loader, parser, and renderer for ambitious projects.
|
||||
It combines the readability of Markdown with the expressivity of JSX.
|
||||
The best of both worlds. :globe_with_meridians:
|
||||
MDX enables you to seamlessly use JSX in your Markdown documents.
|
||||
This makes writing long-form content with components a blast.
|
||||
|
||||
[See the MDX specification](https://github.com/mdx-js/specification)
|
||||
__:heart: Powerful__: MDX makes it effortless to import and render components in your React/JSX-based projects.
|
||||
|
||||
## Features
|
||||
__:computer: Component-based__: Use existing JSX components inside your MDX, and import MDX files as plain components.
|
||||
|
||||
- Fast
|
||||
- No runtime compilation
|
||||
- [Pluggable](https://github.com/remarkjs/remark/blob/master/doc/plugins.md)
|
||||
- Element to React component mapping
|
||||
- React component `import`/`export`
|
||||
- Simpler image syntax
|
||||
- Webpack loader
|
||||
__:fire: Blazingly blazing fast__: MDX has no runtime, all compilation occurs during the build stage.
|
||||
|
||||
> [Watch some of these features in action](https://www.youtube.com/watch?v=d2sQiI5NFAM&list=PLV5CVI1eNcJgCrPH_e6d57KRUTiDZgs0u)
|
||||
|
||||
## Installation
|
||||
> “It's extremely useful for using design system components to render markdown
|
||||
and weaving interactive components in with existing markdown.”
|
||||
>
|
||||
> — [@chrisbiscardi](https://twitter.com/chrisbiscardi/status/1022304288326864896)
|
||||
|
||||
```sh
|
||||
npm install --save-dev @mdx-js/loader @mdx-js/mdx
|
||||
```
|
||||
## Why?
|
||||
|
||||
> Note: mdx requires a version of node that is >= `v8.5`
|
||||
Before MDX, some of the benefits of writing Markdown were lost when integrating with JSX.
|
||||
Implementations were often template string-based which required lots of escaping and cumbersome syntax.
|
||||
|
||||
### Configuring with Webpack
|
||||
MDX seeks to make writing with Markdown _and_ JSX simpler while being more expressive.
|
||||
The possibilities are endless when you combine components (that can even be dynamic or load data) with the simplicity of Markdown for long-form content.
|
||||
|
||||
You'll need to specify the `@mdx-js/loader` webpack loader and follow it with the `babel-loader`:
|
||||
- Fast
|
||||
- No runtime compilation
|
||||
- [Pluggable][remark-plugins]
|
||||
- Element to React component mapping
|
||||
- React component `import`/`export`
|
||||
- Customizable layouts
|
||||
- Webpack loader
|
||||
- Parcel plugin
|
||||
- Next.js plugin
|
||||
- Gatsby plugin
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.md$/,
|
||||
use: ['babel-loader', '@mdx-js/loader']
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p>
|
||||
<details>
|
||||
<summary><b>Examples</b></summary>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="./examples/next"><code>next.js</code></a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="./examples/x0"><code>x0</code></a>
|
||||
</li>
|
||||
</ul>
|
||||
</details>
|
||||
</p>
|
||||
|
||||
### Configuring with Parcel
|
||||
|
||||
You'll need to install the `@mdx-js/parcel-plugin-mdx` plugin to transpile MDX.
|
||||
|
||||
```js
|
||||
{
|
||||
"scripts": {
|
||||
"start": "parcel index.html --no-cache"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "16.4.1",
|
||||
"react-dom": "16.4.1",
|
||||
"@mdx-js/tag": "latest"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@mdx-js/parcel-plugin-mdx": "latest",
|
||||
"parcel-bundler": "1.9.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<p>
|
||||
<details>
|
||||
<summary><b>Examples</b></summary>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="./examples/parcel"><code>Parcel</code></a>
|
||||
</li>
|
||||
</ul>
|
||||
</details>
|
||||
</p>
|
||||
|
||||
### Configuring TypeScript
|
||||
|
||||
If you're getting errors from TypeScript related to imports with an `*.mdx` extension, create an `mdx.d.ts` file in your types directory and include inside your `tsconfig.json`
|
||||
## Getting started
|
||||
|
||||
```
|
||||
// types/mdx.d.ts
|
||||
declare module '*.mdx' {
|
||||
let MDXComponent: (props) => JSX.Element;
|
||||
export default MDXComponent;
|
||||
}
|
||||
npx init mdx
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Create an md file, `hello.md`:
|
||||
|
||||
```jsx
|
||||
# Hello, world!
|
||||
```
|
||||
|
||||
And import it from a component, `pages/index.js`:
|
||||
|
||||
```jsx
|
||||
import React from 'react'
|
||||
import Hello from '../hello.md'
|
||||
|
||||
export default () => <Hello />
|
||||
```
|
||||
|
||||
## MDX syntax
|
||||
|
||||
### Imports
|
||||
|
||||
Similarly to JSX, components can be rendered after an `import`:
|
||||
|
||||
```jsx
|
||||
import Graph from './components/graph'
|
||||
|
||||
## Here's a graph
|
||||
|
||||
<Graph />
|
||||
```
|
||||
|
||||
#### Markdown file transclusion
|
||||
|
||||
You can transclude Markdown files by importing one `.md` file into another:
|
||||
|
||||
```jsx
|
||||
import License from './license.md'
|
||||
import Contributing from './docs/contributing.md'
|
||||
|
||||
# Hello, world!
|
||||
|
||||
<License />
|
||||
|
||||
---
|
||||
|
||||
<Contributing />
|
||||
```
|
||||
|
||||
### Exports
|
||||
|
||||
You can use exports to export metadata like layout or authors.
|
||||
It's a mechanism for an imported MDX file to communicate with its parent.
|
||||
It works similarly to frontmatter, but uses ES2015 syntax.
|
||||
|
||||
```js
|
||||
// posts/post.mdx
|
||||
import { fred, sue } from '../data/authors'
|
||||
import Layout from '../components/blog-layout'
|
||||
|
||||
export const meta = {
|
||||
authors: [fred, sue],
|
||||
layout: Layout
|
||||
}
|
||||
|
||||
# Post about MDX
|
||||
|
||||
MDX is a JSX in Markdown loader, parser, and renderer for ambitious projects.
|
||||
```
|
||||
|
||||
```jsx
|
||||
// index.js
|
||||
import React from 'react'
|
||||
import Mdx, { meta } from 'posts/post.mdx'
|
||||
|
||||
const { authors, layout } = meta
|
||||
|
||||
export default () => (
|
||||
<layout>
|
||||
<Mdx />
|
||||
By: {authors.map(author => author.name)}
|
||||
</layout>
|
||||
)
|
||||
```
|
||||
|
||||
#### `export default`
|
||||
|
||||
The ES default export is used to provide a layout component which will wrap the transpiled JSX.
|
||||
|
||||
You can export it as a function:
|
||||
|
||||
```jsx
|
||||
import Layout from './Layout'
|
||||
|
||||
export default ({children}) => <Layout some='metadata' >{children}</Layout>
|
||||
|
||||
# Hello, world!
|
||||
```
|
||||
|
||||
Or directly as a component:
|
||||
|
||||
```jsx
|
||||
import Layout from './Layout'
|
||||
|
||||
export default Layout
|
||||
|
||||
# Hello, world!
|
||||
```
|
||||
|
||||
Any additional props passed to the imported MDX component will be passed to its default export:
|
||||
|
||||
```jsx
|
||||
// index.js
|
||||
import Mdx from './posts/post.mdx'
|
||||
|
||||
export default () => (
|
||||
<Mdx someProp="value" />
|
||||
)
|
||||
```
|
||||
```js
|
||||
// posts/post.mdx
|
||||
import Layout from '../components/blog-layout'
|
||||
|
||||
# Hello, world!
|
||||
|
||||
export default ({ children, someProp }) => <Layout someProp={someProp}>{children}</Layout>
|
||||
```
|
||||
|
||||
### Component customization
|
||||
|
||||
You can pass in components for any `html` element that Markdown compiles to.
|
||||
This allows you to use your existing components and use CSS-in-JS like `styled-components`.
|
||||
|
||||
```jsx
|
||||
import React from 'react'
|
||||
import Hello from '../hello.md'
|
||||
|
||||
import {
|
||||
Text,
|
||||
Heading,
|
||||
Code,
|
||||
InlineCode
|
||||
} from '../ui'
|
||||
|
||||
export default () =>
|
||||
<Hello
|
||||
components={{
|
||||
h1: Heading,
|
||||
p: Text,
|
||||
code: Code,
|
||||
inlineCode: InlineCode
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
### MDXProvider
|
||||
|
||||
If you're using an app layout that wraps your JSX, you can use the `MDXProvider` to only pass your components in one place:
|
||||
|
||||
```jsx
|
||||
import React from 'react'
|
||||
import { MDXProvider } from '@mdx-js/tag'
|
||||
|
||||
import * as components from './markdown-components'
|
||||
|
||||
export default props =>
|
||||
<MDXProvider components={components}>
|
||||
<main {...props} />
|
||||
</MDXProvider>
|
||||
```
|
||||
|
||||
## Plugins
|
||||
|
||||
Since MDX uses the [remark](https://github.com/remarkjs/remark)/[rehype](https://github.com/rehypejs/rehype) ecosystems, you can use plugins to modify the AST at different stages of the transpilation process.
|
||||
|
||||
If you look at the [next example](https://github.com/mdx-js/mdx/blob/master/examples/next/next.config.js#L3), it shows you to pass plugins as options to the [MDX loader](https://github.com/mdx-js/mdx/tree/master/packages/loader).
|
||||
|
||||
### Options
|
||||
|
||||
Name | Type | Required | Description
|
||||
---- | ---- | -------- | -----------
|
||||
`mdPlugins` | Array[] | `false` | Array of remark plugins to manipulate the MDXAST
|
||||
`hastPlugins` | Array[] | `false` | Array of rehype plugins to manipulate the MDXHAST
|
||||
`skipExport` | Boolean | `false` | Skip `export default` wrapper on transpiled JSX
|
||||
|
||||
#### Specifying plugins
|
||||
|
||||
Plugins need to be passed to the MDX loader via webpack options.
|
||||
|
||||
If a plugin needs specific options, use the `[plugin, pluginOptions]` syntax.
|
||||
|
||||
```js
|
||||
const images = require('remark-images')
|
||||
const emoji = require('remark-emoji')
|
||||
const toc = require('remark-toc')
|
||||
|
||||
module.exports = {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.mdx?$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'babel-loader'
|
||||
},
|
||||
{
|
||||
loader: '@mdx-js/loader',
|
||||
options: {
|
||||
mdPlugins: [images, emoji, [toc, {heading: 'intro'}]]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##### Next.js
|
||||
|
||||
If you're using Next.js, you can specify options in your `next.config.js`.
|
||||
|
||||
```js
|
||||
const images = require('remark-images')
|
||||
const emoji = require('remark-emoji')
|
||||
|
||||
module.exports = {
|
||||
pageExtensions: ['js', 'jsx', 'md', 'mdx'],
|
||||
webpack: (config, { defaultLoaders }) => {
|
||||
config.module.rules.push({
|
||||
test: /\.md$/,
|
||||
use: [
|
||||
defaultLoaders.babel,
|
||||
{
|
||||
loader: '@mdx-js/loader',
|
||||
options: {
|
||||
mdPlugins: [images, emoji]
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
return config
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Sync API
|
||||
|
||||
If you're using the MDX library directly, you might want to process an MDX string synchronously.
|
||||
|
||||
```js
|
||||
const jsx = mdx.sync('# Hello, world!')
|
||||
```
|
||||
- [Documentation](https://mdxjs.com)
|
||||
- [Syntax](https://mdxjs.com/syntax)
|
||||
- [Getting Started](https://mdxjs.com/getting-started)
|
||||
- [Plugins](https://mdxjs.com/plugins)
|
||||
- [Contributing](https://mdxjs.com/advanced/contributing)
|
||||
|
||||
## Related
|
||||
|
||||
@ -368,3 +60,7 @@ const jsx = mdx.sync('# Hello, world!')
|
||||
- Tim Neutkens ([@timneutkens](https://github.com/timneutkens)) – [ZEIT](https://zeit.co)
|
||||
- Guillermo Rauch ([@rauchg](https://twitter.com/rauchg)) – [ZEIT](https://zeit.co)
|
||||
- Brent Jackson ([@jxnblk](https://twitter.com/jxnblk)) – [Compositor](https://compositor.io)
|
||||
|
||||
---
|
||||
|
||||
> [MIT](./license) license
|
||||
|
Loading…
Reference in New Issue
Block a user