Skip to content

Instantly share code, notes, and snippets.

@josefaidt
Last active January 25, 2023 16:26
Show Gist options
  • Select an option

  • Save josefaidt/aca65f4a537caaa84ce3419107715c1a to your computer and use it in GitHub Desktop.

Select an option

Save josefaidt/aca65f4a537caaa84ce3419107715c1a to your computer and use it in GitHub Desktop.

Revisions

  1. josefaidt revised this gist Jan 25, 2023. 1 changed file with 22 additions and 0 deletions.
    22 changes: 22 additions & 0 deletions MDXProvider.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,22 @@
    import React from 'react';
    import { MDXProvider as StockMDXProvider } from '@mdx-js/react';
    import type { PropsWithChildren } from 'react';

    const wrapper = ({ children, frontmatter }) => {
    console.log('mdx page props', { props: { frontmatter } });
    return <Page meta={frontmatter}>{children}</Page>;
    };

    const shortcodes = {
    wrapper
    };

    type MDXProviderProps = PropsWithChildren<{}>;

    function MDXProvider ({ children }: MDXProviderProps) {
    return (
    <StockMDXProvider components={shortcodes}>{children}</StockMDXProvider>
    );
    };

    export default MDXProvider;
  2. josefaidt created this gist Jan 25, 2023.
    4 changes: 4 additions & 0 deletions plugins.d.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,4 @@
    type RecmaMdxFrontmatterPluginOptions = {
    // maybe we'll add something here
    name: string = 'frontmatter';
    };
    49 changes: 49 additions & 0 deletions recma-mdx-frontmatter.mjs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,49 @@
    /// <reference path="./plugins.d.ts" />
    import { fromJs } from 'esast-util-from-js';
    import { visit } from 'estree-util-visit';

    /**
    * Plugin to pass frontmatter to getStaticProps and into MDXProvider's `wrapper`
    * @returns {import('unified').Plugin<[RecmaMdxFrontmatterPluginOptions], import('estree').Program>}
    */
    export const recmaMdxFrontmatter = (options) => {
    const { name = 'frontmatter' } = options || {};
    /**
    * Transformer
    * @param {import('estree').Program} tree
    */
    const transformer = (tree) => {
    const frontmatter = {};
    visit(tree, (node) => {
    // look for `frontmatter` variable created by remark-mdx-frontmatter
    if (node.type === 'VariableDeclarator' && node.id.name === name) {
    if (!Array.isArray(node.init.properties)) return;
    // collect frontmatter props
    for (const prop of node.init.properties) {
    frontmatter[prop.key.value] = prop.value.value;
    }
    }
    });
    // create `getStaticProps` to feed frontmatter to MDXProvider's `wrapper`
    const getStaticProps = fromJs(
    `
    export const getStaticProps = async () => {
    return {
    props: {
    frontmatter: ${JSON.stringify(frontmatter)}
    }
    }
    }
    `,
    {
    // sourceType: 'module',
    module: true
    }
    );
    // push `getStaticProps` to end of tree
    tree.body.push(...getStaticProps.body);
    };
    return transformer;
    };

    export default recmaMdxFrontmatter;