Giter VIP home page Giter VIP logo

gatsby-mdx's Introduction

Gatsby MDX

MDX integration with Gatsby for ambitious projects.

Initial Setup

npm install gatsby-mdx @mdx-js/mdx @mdx-js/tag

then add gatsby-mdx to your gatsby-config.js in the plugins section.

module.exports = {
  siteMetadata: {
    title: `My Ambitious Project`
  },
  plugins: [`gatsby-mdx`]
};

Note: gatsby-mdx is only compatible with Gatsby version 2 or newer.

Writing Pages in MDX

Add an .mdx file in the src/pages directory. It "Just Works".

# My first MDX Page

some awesome content

Plugin Options

File Extensions

gatsby-mdx can apply to different file extensions. By default it conservatively applies to only .mdx files, but can also be made to apply to .md files.

module.exports = {
  plugins: [
    {
      resolve: `gatsby-mdx`,
      options: {
        extensions: [".mdx", ".md"]
      }
    }
  ]
};

Default Layouts

MDX supports layouts using the default export as such:

export default ({ children }) => (
  <div>
    <h1>My Layout</h1>
    <div>{children}</div>
  </div>
)


# My MDX

some content

or as an import:

import PageLayout from './src/components/page-layout';
export PageLayout

# My MDX

some content

Sometimes you don't want to include the layout in every file, so gatsby-mdx offers the option to set default layouts in the gatsby-config.js plugin config. Set the key to the name set in the gatsby-source-filesystem config. If no matching default layout is found, the default default layout is used.

You can also set options.defaultLayout if you only want to use one layout for all MDX pages.

module.exports = {
  siteMetadata: {
    title: `Gatsby MDX Kitchen Sink`
  },
  plugins: [
    {
      resolve: `gatsby-mdx`,
      options: {
        defaultLayouts: {
          posts: require.resolve("./src/components/posts-layout.js"),
          default: require.resolve("./src/components/default-page-layout.js")
        }
      }
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `posts`,
        path: `${__dirname}/src/posts/`
      }
    }
  ]
};

GraphQL

MDX files can be queried with allMdx on the root query. Like gatsby-transformer-remark, this plugin adds fields to the Mdx node including excerpt, headings, timeToRead, and wordCount.

All static exports โ€“ values that would be valid JSON โ€“ are queryable through the exports field.

query MDXQuery {
  allMdx {
    edges {
      node {
        relativePath
        fileAbsolutePath
        fileNode {
          name
        }
        timeToRead
        frontmatter {
          title
        }
        exports {
          author
        }
      }
    }
  }
}

Programmatically Creating Pages

Pages can be created programmatically by combining gatsby-source-filesystem in gatsby-config.js with some createPage calls.

# gatsby-config.js
module.exports = {
  plugins: [
  `gatsby-mdx`,
    {
      resolve: "gatsby-source-filesystem",
      options: {
        name: "posts",
        path: `${__dirname}/content/`
      }
    }
  ]
};
# gatsby-node.js
exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions;
  return new Promise((resolve, reject) => {
    resolve(
      graphql(
        `
          {
            allMdx {
              edges {
                node {
                  fileAbsolutePath
                  fileNode {
                    name
                  }
                }
              }
            }
          }
        `
      ).then(result => {
        if (result.errors) {
          console.log(result.errors);
          reject(result.errors);
        }

        // Create blog posts pages.
        result.data.allMdx.edges.forEach(({ node }) => {
          createPage({
            path: `/non-page/${node.fileNode.name}`,
            component: node.fileAbsolutePath, //blogPost,
            context: { absPath: node.absolutePath }
          });
        });
      })
    );
  });
};

Getting Ambitious

Using Design System Components

Using MDX, you can replace every HTML element that Markdown renders with a custom implementation. This allows you to use a set of design system components when rendering Markdown.

// src/components/layout.js

import { MDXProvider } from "@mdx-js/tag";
import * as DesignSystem from "your-design-system";

export default function Layout({ children }) {
  return (
    <MDXProvider
      components={{
        // Map HTML element tag to React component
        h1: DesignSystem.H1,
        h2: DesignSystem.H2,
        h3: DesignSystem.H3,
        // Or define component inline
        p: props => <p {...props} style={{ color: "rebeccapurple" }} />
      }}
    >
      {children}
    </MDXProvider>
  );
}

Editable Code Blocks

To make every markdown code block an editable live example, you can pass in a custom code element to MDXProvider.

react-live

import React, {Component} from "react";
import { LiveProvider, LiveEditor, LiveError, LivePreview } from "react-live";
import { MDXProvider } from '@mdx-js/tag'

const MyCodeComponent = ({ children, ...props }) => (
  <LiveProvider code={children}>
    <LiveEditor />
    <LiveError />
    <LivePreview />
  </LiveProvider>
);

export default MyPageLayout extends Component {
  render() {
    return <MDXProvider components={{code: MyCodeComponent}}>
      <div>{this.props.children}</div>
    </MDXProvider>
  }
}

Experimental

Experimental things could be volatile. Use at your own risk.

MDX Deck

To embed mdx-deck presentations in your gatsby site, add mdx deck to your dependencies (in addition to the gatsby-mdx and it's dependencies).

npm install mdx-deck

Add the relevant config to your gatsby-config.js. In this example, we use set the required decks key in the gatsby-mdx plugin config to point to our folder of slide decks and the filesystem source to point to our decks folder. We also set a defaultLayout that wraps every individual slide.

const path = require("path");

module.exports = {
  siteMetadata: {
    title: `Gatsby MDX Kitchen Sink`
  },
  plugins: [
    `gatsby-plugin-emotion`,
    `gatsby-plugin-react-helmet`,
    {
      resolve: `gatsby-mdx`,
      options: {
        extensions: [".mdx", ".md"],
        decks: [path.resolve("./decks")],
        defaultLayouts: {
          default: require.resolve("./src/components/default-page-layout.js"),
          slides: require.resolve("./src/components/default-slide-layout.js")
        }
      }
    },
    {
      resolve: "gatsby-source-filesystem",
      options: {
        name: "slides",
        path: `${__dirname}/decks/`
      }
    },
    `gatsby-plugin-offline`
  ]
};

gatsby-mdx's People

Contributors

christopherbiscardi avatar avigoldman avatar kruton avatar macklinu avatar ryaninvents avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.