最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Gatsby doesn't render MD in component inside of mdx file - Stack Overflow

programmeradmin2浏览0评论

What is working:

  • The layout is correctly applied to each of my pages
  • The MDX file correctly gets the Hero and section ponent and renders the HTML/CSS of the container correctly
  • The data from MDX is loaded and displayed

What is NOT working:

  • The MD within the Hero or the Section Shortcode is not being rendered! # is not transformed into H1 etc.

What i have tried:

  • Using the MDXRender in Section & Hero => Error
  • Use the ponent directly in the MDX file instead of shortcode

Question:

  • Is it not possible to render the MD correctly within the shortcode? In other words, is the MDX not rendered recurisvely?

content/index.mdx:

---
title: Main Content English
slug: /main-content/
---

<Hero># This is a test, but never gets transformed</Hero>

<Section># In Section Headline</Section>

# ABC

Officia cillum _asdasd_ et duis dolor occaecat velit culpa. Cillum eu sint adipisicing labore incididunt nostrud tempor fugiat. Occaecat ex id fugiat laborum ullamco. Deserunt sint quis aliqua consequat ullamco Lorem dolor pariatur laboris. Laborum officia ut magna exercitation elit velit mollit do. Elit minim nostrud cillum reprehenderit deserunt consequat. Aliqua ex cillum sunt exercitation deserunt sit aliquip aliquip ea proident cillum quis.

My layout.js looks like this:

import React, {useEffect} from "react";

import "./Layout.css";

import { MDXProvider } from "@mdx-js/react";
import { MdxLink } from "gatsby-theme-i18n";
...

import Hero from "../Hero/HomepageHero/HomepageHero"
import Section from "../Section/Section"


const ponents = {
  a: MdxLink,
  Hero, Section
};


export default function Layout({ children }) {
   ...
  return (
    <div className="appGrid">
      <Header />

      <ScrollToTopButton />

      <div className="cell contentCell">
        <MDXProvider ponents={ponents}>{children}</MDXProvider>
      </div>

      <Footer />

      <Copyright />
    </div>
  );
}

my index.js page (loaded automatically) looks like this:

import * as React from "react";

import { graphql } from "gatsby";

import Layout from "../ponents/Layout/layout";
import { MDXRenderer } from "gatsby-plugin-mdx";


const IndexPage = ({ data }) => {

  return (
    <Layout>
      {data.allFile.nodes.map(({ childMdx: node }) => (
        <div>
          {node ? (
            <MDXRenderer>{node.body}</MDXRenderer>
          ) : (
            <div>This page has not been translated yet.</div>
          )}
        </div>
      ))}
    </Layout>
  );
};

export default IndexPage;

export const query = graphql`
  query($locale: String!) {
    allFile(
      filter: {
        sourceInstanceName: { eq: "content" }
        childMdx: { fields: { locale: { eq: $locale } } }
      }
    ) {
      nodes {
        childMdx {
          body
        }
      }
    }
  }
`;

Gatsby Config:

module.exports = {
  siteMetadata: {
    siteUrl: "localhost:8000",
    title: "app",
  },
  plugins: [
    {
      resolve: "gatsby-plugin-google-analytics",
      options: {
        trackingId: "",
      },
    },
    "gatsby-plugin-sharp",
    "gatsby-plugin-react-helmet",
    "gatsby-plugin-sitemap",
    "gatsby-plugin-offline",
    {
      resolve: "gatsby-plugin-manifest",
      options: {
        icon: "src/images/icon.png",
      },
    },
    "gatsby-transformer-sharp",
    {
      resolve: "gatsby-source-filesystem",
      options: {
        name: "images",
        path: "./src/images/",
      },
      __key: "images",
    },
    {
      resolve: `gatsby-theme-i18n`,
      options: {
        defaultLang: `en`,
        locales: `en el de`,
        configPath: require.resolve(`${__dirname}/i18n/config.json`),
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `pages`,
        path: `${__dirname}/src/pages/`,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `content`,
        path: `${__dirname}/src/content/`,
      },
    },
    {
      resolve: `gatsby-plugin-mdx`,
      options: {
        defaultLayouts: {
          default: require.resolve(`./src/ponents/Layout/layout.js`),
        },
      },
    },
  ],
};

Section.js Component

import React from "react";
import PropTypes from "prop-types";
import "./Section.css";

export default function Section(props) {
  let content = props.children
  if (props.centered) {
    content = (
      <div className="grid-container ">
        {props.children}
      </div>
    );
  }
  return <div className="section">{content}</div>;
}

Section.propTypes = {
  centered: PropTypes.bool,
  children: PropTypes.element,
};

What is working:

  • The layout is correctly applied to each of my pages
  • The MDX file correctly gets the Hero and section ponent and renders the HTML/CSS of the container correctly
  • The data from MDX is loaded and displayed

What is NOT working:

  • The MD within the Hero or the Section Shortcode is not being rendered! # is not transformed into H1 etc.

What i have tried:

  • Using the MDXRender in Section & Hero => Error
  • Use the ponent directly in the MDX file instead of shortcode

Question:

  • Is it not possible to render the MD correctly within the shortcode? In other words, is the MDX not rendered recurisvely?

content/index.mdx:

---
title: Main Content English
slug: /main-content/
---

<Hero># This is a test, but never gets transformed</Hero>

<Section># In Section Headline</Section>

# ABC

Officia cillum _asdasd_ et duis dolor occaecat velit culpa. Cillum eu sint adipisicing labore incididunt nostrud tempor fugiat. Occaecat ex id fugiat laborum ullamco. Deserunt sint quis aliqua consequat ullamco Lorem dolor pariatur laboris. Laborum officia ut magna exercitation elit velit mollit do. Elit minim nostrud cillum reprehenderit deserunt consequat. Aliqua ex cillum sunt exercitation deserunt sit aliquip aliquip ea proident cillum quis.

My layout.js looks like this:

import React, {useEffect} from "react";

import "./Layout.css";

import { MDXProvider } from "@mdx-js/react";
import { MdxLink } from "gatsby-theme-i18n";
...

import Hero from "../Hero/HomepageHero/HomepageHero"
import Section from "../Section/Section"


const ponents = {
  a: MdxLink,
  Hero, Section
};


export default function Layout({ children }) {
   ...
  return (
    <div className="appGrid">
      <Header />

      <ScrollToTopButton />

      <div className="cell contentCell">
        <MDXProvider ponents={ponents}>{children}</MDXProvider>
      </div>

      <Footer />

      <Copyright />
    </div>
  );
}

my index.js page (loaded automatically) looks like this:

import * as React from "react";

import { graphql } from "gatsby";

import Layout from "../ponents/Layout/layout";
import { MDXRenderer } from "gatsby-plugin-mdx";


const IndexPage = ({ data }) => {

  return (
    <Layout>
      {data.allFile.nodes.map(({ childMdx: node }) => (
        <div>
          {node ? (
            <MDXRenderer>{node.body}</MDXRenderer>
          ) : (
            <div>This page has not been translated yet.</div>
          )}
        </div>
      ))}
    </Layout>
  );
};

export default IndexPage;

export const query = graphql`
  query($locale: String!) {
    allFile(
      filter: {
        sourceInstanceName: { eq: "content" }
        childMdx: { fields: { locale: { eq: $locale } } }
      }
    ) {
      nodes {
        childMdx {
          body
        }
      }
    }
  }
`;

Gatsby Config:

module.exports = {
  siteMetadata: {
    siteUrl: "localhost:8000",
    title: "app",
  },
  plugins: [
    {
      resolve: "gatsby-plugin-google-analytics",
      options: {
        trackingId: "",
      },
    },
    "gatsby-plugin-sharp",
    "gatsby-plugin-react-helmet",
    "gatsby-plugin-sitemap",
    "gatsby-plugin-offline",
    {
      resolve: "gatsby-plugin-manifest",
      options: {
        icon: "src/images/icon.png",
      },
    },
    "gatsby-transformer-sharp",
    {
      resolve: "gatsby-source-filesystem",
      options: {
        name: "images",
        path: "./src/images/",
      },
      __key: "images",
    },
    {
      resolve: `gatsby-theme-i18n`,
      options: {
        defaultLang: `en`,
        locales: `en el de`,
        configPath: require.resolve(`${__dirname}/i18n/config.json`),
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `pages`,
        path: `${__dirname}/src/pages/`,
      },
    },
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `content`,
        path: `${__dirname}/src/content/`,
      },
    },
    {
      resolve: `gatsby-plugin-mdx`,
      options: {
        defaultLayouts: {
          default: require.resolve(`./src/ponents/Layout/layout.js`),
        },
      },
    },
  ],
};

Section.js Component

import React from "react";
import PropTypes from "prop-types";
import "./Section.css";

export default function Section(props) {
  let content = props.children
  if (props.centered) {
    content = (
      <div className="grid-container ">
        {props.children}
      </div>
    );
  }
  return <div className="section">{content}</div>;
}

Section.propTypes = {
  centered: PropTypes.bool,
  children: PropTypes.element,
};

Share Improve this question edited Dec 29, 2020 at 12:24 Ferran Buireu 29.3k7 gold badges46 silver badges72 bronze badges asked Dec 29, 2020 at 11:28 RichardRichard 1,5903 gold badges26 silver badges53 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

In the end it was a simple spacing issue.

It works perfectly fine without any additional work:

---
title: Main Content English
slug: /main-content/
---

<Hero>

# This is a test, but never gets transformed

</Hero>

<Section>

# In Section Headline

</Section>

...

Be aware of the empty lines!

With MDX you are rendering JSX inside a Markdown (MD + JSX) file so, # it's not recognized as a shortcode when it's wrapped by a JSX ponent when it's in the same declarative line:

Change:

<Hero># This is a test, but never gets transformed</Hero>

To:

<Hero>
    # This is a test, but never gets transformed
</Hero>

Alternatively, you can also change:

<Hero># This is a test, but never gets transformed</Hero>

To:

<Hero><h1> This is a test, but never gets transformed</h1></Hero>

Another thing that may work for you is using a Markdown parser (like markdown-to-jsx) and:

---
title: Main Content English
slug: /main-content/
---

import Markdown from 'markdown-to-jsx';


<Hero><Markdown># This is a test, but never gets transformed</Markdown></Hero>

<Section><Markdown># In Section Headline</Markdown></Section>

# ABC

Officia cillum _asdasd_ et duis dolor occaecat velit culpa. Cillum eu sint adipisicing labore incididunt nostrud tempor fugiat. Occaecat ex id fugiat laborum ullamco. Deserunt sint quis aliqua consequat ullamco Lorem dolor pariatur laboris. Laborum officia ut magna exercitation elit velit mollit do. Elit minim nostrud cillum reprehenderit deserunt consequat. Aliqua ex cillum sunt exercitation deserunt sit aliquip aliquip ea proident cillum quis.

Alternatively, you add a custom mapping ponent, as you do with MdxLink but using your own ponent to parse the children as <Markdown> dependency does.

发布评论

评论列表(0)

  1. 暂无评论