Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[gatsby-plugin-mdx] Images within <figure> nested within <p> tags are invalid #16239

Closed
chasemccoy opened this issue Jul 31, 2019 · 15 comments
Closed
Labels
topic: remark/mdx

Comments

@chasemccoy
Copy link
Contributor

@chasemccoy chasemccoy commented Jul 31, 2019

Description

When using gatsby-plugin-mdx with gatsby-remark-images, images written in Markdown are being wrapped in a <p> tag, which fails React's DOM nesting validation because elements like <figure> and <figcaption> (which area generated by gatsby-remark-images) are not valid with <p> tags.

Steps to reproduce

Render a Markdown image:

![Alt text](image.png)

In a Gatsby site using gatsby-plugin-mdx and gatsby-remark-images.

Expected result

The image would not be nested within a paragraph tag.

Actual result

The image is nested within a <p> tag, which caused DOM validation to fail:

Screen Shot 2019-07-30 at 9 52 30 PM

Environment


  System:
    OS: macOS 10.14.5
    CPU: (8) x64 Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 10.15.1 - ~/.nvm/versions/node/v10.15.1/bin/node
    Yarn: 1.16.0 - ~/.yarn/bin/yarn
    npm: 6.9.0 - ~/.nvm/versions/node/v10.15.1/bin/npm
  Languages:
    Python: 2.7.10 - /usr/bin/python
  Browsers:
    Chrome: 75.0.3770.142
    Firefox: 64.0
    Safari: 12.1.1
  npmPackages:
    gatsby: 2.8.6 => 2.8.6 
    gatsby-image: 2.1.2 => 2.1.2 
    gatsby-plugin-favicon: 3.1.6 => 3.1.6 
    gatsby-plugin-feed: 2.2.3 => 2.2.3 
    gatsby-plugin-layout: 1.0.15 => 1.0.15 
    gatsby-plugin-mdx: ^1.0.7 => 1.0.7 
    gatsby-plugin-page-creator: 2.0.13 => 2.0.13 
    gatsby-plugin-react-helmet: 3.0.12 => 3.0.12 
    gatsby-plugin-sharp: 2.1.3 => 2.1.3 
    gatsby-plugin-styled-components: 3.0.7 => 3.0.7 
    gatsby-plugin-twitter: 2.0.13 => 2.0.13 
    gatsby-remark-autolink-headers: 2.0.16 => 2.0.16 
    gatsby-remark-copy-linked-files: ^2.1.3 => 2.1.3 
    gatsby-remark-external-links: 0.0.4 => 0.0.4 
    gatsby-remark-images: 3.1.2 => 3.1.2 
    gatsby-source-airtable: 2.0.8 => 2.0.8 
    gatsby-source-filesystem: 2.0.38 => 2.0.38 
    gatsby-source-github: ^0.0.2 => 0.0.2 
    gatsby-source-wordpress: 3.0.64 => 3.0.64 
    gatsby-transformer-hjson: 2.1.8 => 2.1.8 
    gatsby-transformer-json: 2.1.11 => 2.1.11 
    gatsby-transformer-remark: 2.3.12 => 2.3.12 
    gatsby-transformer-sharp: 2.1.21 => 2.1.21 
  npmGlobalPackages:
    gatsby-cli: 2.6.5
@chasemccoy
Copy link
Contributor Author

@chasemccoy chasemccoy commented Jul 31, 2019

cc @ChristopherBiscardi @johno

@chasemccoy chasemccoy changed the title [gatsby-plugin-mdx] Images nested within <p> tags are invalid DOM nesting [gatsby-plugin-mdx] Images within <figure> nested within <p> tags are invalid Jul 31, 2019
@chasemccoy
Copy link
Contributor Author

@chasemccoy chasemccoy commented Jul 31, 2019

This might require making sure that gatsby-remark-images is configured to show captions under images.

@gatsbot gatsbot bot added the stale? label Aug 21, 2019
@RobertBroersma
Copy link

@RobertBroersma RobertBroersma commented Aug 26, 2019

I'm also experiencing this issue. Only when writing an alt text in Markdown like so:

![Alt text](image.png)

It seems like it doesn't matter if I configure showCaptions or markdownCaptions in my config, the alt text shows up anyway if it exists. But I suppose that is a separate issue!

@gatsbot gatsbot bot closed this as completed Sep 6, 2019
@johno johno reopened this Sep 6, 2019
@johno johno added not stale and removed stale? labels Sep 6, 2019
@rejas
Copy link

@rejas rejas commented Jan 26, 2020

I just stumbled over this too.

In my gatsby config i use the mdx plugin together with the remarkplugin like this:

    {
      resolve: 'gatsby-plugin-mdx',
      options: {
        defaultLayouts: {
          default: require.resolve(
            `${__dirname}/src/components/page/Layout.jsx`
          ),
        },
        extensions: ['.mdx', '.md'],
        gatsbyRemarkPlugins: [
          {
            resolve: 'gatsby-remark-images',
            options: {
              linkImagesToOriginal: false,
              showCaptions: true,
              withWebp: true,
            },
          },
        ],
        plugins: ['gatsby-remark-images'],
      },
    },

and my images are rendered with this error in the console:

Warning: validateDOMNesting(...): <figure> cannot appear as a descendant of <p>.
    in figure (created by MDXCreateElement)

It renders but the error is of course annoying, is there anything I can do to get this fixed?

@muuvmuuv
Copy link

@muuvmuuv muuvmuuv commented Feb 3, 2020

Maybe related to this? #15486
I think the issue is with the plugin handling itself as discussed in the above issue. Hopefully a fix will come soon!

@onadeem1
Copy link

@onadeem1 onadeem1 commented Mar 3, 2020

I am having this same issue but with the gatsby embed video or gatsby responsive iframe, one of them creates a <div> which goes inside the <p> tag for markdown. Any updates? Thanks. Can add more info if needed but essentially the same problem.

@muuvmuuv
Copy link

@muuvmuuv muuvmuuv commented Mar 4, 2020

Found a workaround for the image issue, just add remark-unwrap-images:

const mdxImageWrapFix = {
  resolve: `gatsby-plugin-mdx`,
  options: {
    plugins: [`gatsby-remark-images`],
    remarkPlugins: [require('remark-unwrap-images')],
    gatsbyRemarkPlugins: [
      'gatsby-remark-images',
    ],
  },
},

I guess it should be easy to adapt this plugin to embedded video and others as well.

@mmgolden
Copy link

@mmgolden mmgolden commented Apr 22, 2020

Is there an official fix coming for this yet? I have the same problem.

{
      resolve: `gatsby-plugin-mdx`,
      options: {
        extensions: [`.mdx`, `.md`],
        gatsbyRemarkPlugins: [
          {
            resolve: `gatsby-remark-images`,
            options: {
              maxWidth: 756,
              showCaptions: true,
              quality: 80,
            },
          },
        ],
      },
    },
Warning: validateDOMNesting(...): <figure> cannot appear as a descendant of <p>.

@rejas
Copy link

@rejas rejas commented Apr 23, 2020

thanks for the tip @muuvmuuv worked for me once I removed the markdownCaptions option from my gatsby-remark-images options.

@joyfulelement
Copy link
Contributor

@joyfulelement joyfulelement commented Jun 16, 2020

I am having this same issue but with the gatsby embed video or gatsby responsive iframe, one of them creates a <div> which goes inside the <p> tag for markdown. Any updates? Thanks. Can add more info if needed but essentially the same problem.

Issue with embedding video that gives <div> cannot appear as a descendant of <p>

Here are the current dependency line up I used to reproduce this issue:

    "@mdx-js/mdx": "1.6.5",
    "@mdx-js/react": "1.6.5",
    "gatsby": "2.23.3",
    "gatsby-plugin-mdx": "1.2.15",
    "gatsby-remark-images": "3.3.10",
    "remark-unwrap-images": "2.0.0",

I can also verify there is an issue @onadeem1 pointed out when MDX wraps HTML markup tags coming from gatsby-remark-embed-video with gatsby-remark-responsive-iframe. The resulting HTML becomes

<p>
  <undefined>
      <div class="gatsby-resp-iframe-wrapper" style="...">
          <div class="embedVideo-container">
              <iframe src="..." class="embedVideo-iframe" allowfullscreen="" style="...">...</iframe>
          </div>
      </div>
  </undefined>
</p>

along with the following error on the console

Warning: validateDOMNesting(...): <div> cannot appear as a descendant of <p>.
    in div (created by MDXCreateElement)
    in MDXCreateElement (created by MDXContent)
    in div (created by MDXCreateElement)
    in MDXCreateElement (created by MDXContent)
    in undefined (created by MDXCreateElement)
    in MDXCreateElement (created by MDXContent)
    in p (created by MDXCreateElement)
    in MDXCreateElement (created by MDXContent)
    in wrapper (created by MDXCreateElement)
    in MDXCreateElement (created by MDXContent)
    in MDXContent (created by MDXRenderer)
    in MDXRenderer (at Bodytext.js:20)
    ...

What should have been rendered?

If I were to use the regular .md markup with gatsby-transformer-remark without MDX support, the HTML markup does not wrap <div> within <p>

<div class="gatsby-resp-iframe-wrapper" style="...">
  <div class="embedVideo-container">
    <iframe src="..." class="embedVideo-iframe" allowfullscreen="" style="...">...</iframe>
  </div>
</div>

Workaround with remark-unwrap-images does not solve the markup wrapping issue from embedded video

Tried adding remark-unwrap-images as suggested by @muuvmuuv which workaround the issue Images within <figure> nested within <p> tags are invalid by unwrapping image from gatsby-remark-images. However, it does not help with the issue from gatsby-remark-embed-video as pointed out above.

Curious if remark-unwrap-images could be extended to help solve the issue with embedded video? Perhaps the official solution should really be coming out from gatsby-plugin-mdx without the need for these workarounds. Would love to help, but not sure where to start, any pointers would be grateful!

@gatsbyjs gatsbyjs deleted a comment from gatsbot bot Jul 20, 2020
@gatsbyjs gatsbyjs deleted a comment from gatsbot bot Jul 20, 2020
@thomaswang
Copy link
Contributor

@thomaswang thomaswang commented Jul 22, 2020

Running into a similar issue with gatsby-remark-embed-gist and gatsby-plugin-mdx

Using the config weirdpattern/gatsby-remark-embed-gist#12 gives these errors:

Warning: validateDOMNesting(...): <div> cannot appear as a descendant of <p>.
The tag <undefined> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.

tnetennba3 added a commit to tnetennba3/helena that referenced this issue Feb 24, 2021
@coldice
Copy link

@coldice coldice commented Apr 8, 2021

Be careful, everything might appear to be working, however when running the production build and reloading a page where this error is thrown, a bunch of other elements are blown by this. When navigating away and back, all looks good so this only triggers on first load / forced reload.

Using the unwrap plugin, you can actually enable the image captions and everything works fine. I followed this approach: #24832 (comment)

On the issue with the video component, I have now resorted to write my own wrapper component, which bypasses all the markdown nesting issues and allows better control of the settings (like using nocookie). There is a lovely samplecode at https://www.gatsbyjs.com/docs/how-to/images-and-media/working-with-video/

@kimbaudi
Copy link
Contributor

@kimbaudi kimbaudi commented Apr 10, 2021

similar issue. gatsby-plugin-mdx with gatsby-remark-embed-snippet is throwing validateDOMNesting warning:

Warning: validateDOMNesting(...): <pre> cannot appear as a descendant of <p>.

@LekoArts
Copy link
Contributor

@LekoArts LekoArts commented Jan 10, 2022

Hi!

I'm closing this as a stale issue as in the meantime Gatsby 4 and related packages were released. You can check our Framework Version Support Page to see which versions currently receive active support.

Please try the mentioned issue on the latest version (using the next tag) and if you still see this problem, open a new bug report. It must include a minimal reproduction.

Thanks!

@dinhanhthi
Copy link

@dinhanhthi dinhanhthi commented Apr 24, 2022

Found a workaround for the image issue, just add remark-unwrap-images:

const mdxImageWrapFix = {
  resolve: `gatsby-plugin-mdx`,
  options: {
    plugins: [`gatsby-remark-images`],
    remarkPlugins: [require('remark-unwrap-images')],
    gatsbyRemarkPlugins: [
      'gatsby-remark-images',
    ],
  },
},

I guess it should be easy to adapt this plugin to embedded video and others as well.

I got this error

Error: [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/thi/git/dat-5/node_modules/remark-unwrap-images/index.js
  require() of ES modules is not supported.
  require() of /Users/thi/git/dat-5/node_modules/remark-unwrap-images/index.js from /Users/thi/git/dat-5/gatsby-config.js is an ES module file as it is a .js file whose nearest parent packa
  ge.json contains "type": "module" which defines all .js files in that package scope as ES modules.
  Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/thi/git/dat-5/node_modules/remark-unwrap-images/package.json.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: remark/mdx
Projects
None yet
Development

No branches or pull requests