Gatsby: [gatsby-plugin-mdx] ALL root-relative markdown links are broken, prefixed with assetPrefix

Created on 14 Feb 2020  路  10Comments  路  Source: gatsbyjs/gatsby

Description

When generating .mdx pages using gatsby-plugin-mdx, any root-relative links such as [hello](/some-page) are prefixed with assetPrefix for some reason. Obviously, links are not assets and shouldn't receive an assetPrefix.

Steps to reproduce

  1. Create an MDX page; e.g. /pages/hello.mdx

  2. Add a markdown link to that file:

Please review our [privacy policy](/privacy) for more details.
  1. Specify an assetPrefix in gatsby-config.js:
module.exports = {
    assetPrefix: 'https://static.howchoo.com',
    developMiddleware: (app) => {
  1. Build and serve Gatsby with path prefixes enabled: gatsby build --prefix-paths && gatsby serve

  2. Visit the page in your browser and observe the HTML output.

Expected result

The output of the above markdown should be:

<p>Please review our <a href="/privacy">privacy policy</a> for more details.</p>

Actual result

The output of the above markdown actually is:

<p>Please review our <a href="https:/static.howchoo.com/privacy">privacy policy</a> for more details.</p>

Might be related: In addition, it also outputs https:/ instead of https:// (with one slash) for some reason鈥攅ither way, it should just output /privacy.

Additional notes:

  • Root-relative links work elsewhere on the site (in normal React components etc.); this issue happens specifically when using root-relative links in .mdx files.
  • Asset prefixing for ASSETS (images etc.) work as expected elsewhere on the site (in normal React components etc.)

Environment

System:
    OS: macOS 10.15.3
    CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.8.0 - /usr/local/bin/node
    npm: 6.10.3 - /usr/local/bin/npm
  Languages:
    Python: 2.7.16 - /usr/bin/python
  Browsers:
    Chrome: 80.0.3987.106
    Firefox: 71.0
    Safari: 13.0.5
  npmPackages:
    gatsby: ^2.19.5 => 2.19.5
    gatsby-plugin-disqus: ^1.1.4 => 1.1.4
    gatsby-plugin-google-analytics: ^2.1.34 => 2.1.34
    gatsby-plugin-google-tagmanager: ^2.1.24 => 2.1.24
    gatsby-plugin-less: ^3.0.18 => 3.0.18
    gatsby-plugin-lodash: ^3.1.19 => 3.1.19
    gatsby-plugin-manifest: ^2.2.38 => 2.2.38
    gatsby-plugin-mdx: ^1.0.67 => 1.0.67
    gatsby-plugin-offline: ^3.0.32 => 3.0.32
    gatsby-plugin-react-helmet: ^3.1.21 => 3.1.21
    gatsby-plugin-react-svg: ^3.0.0 => 3.0.0
    gatsby-plugin-remove-trailing-slashes: ^2.1.20 => 2.1.20
    gatsby-plugin-sass: ^2.1.27 => 2.1.27
    gatsby-plugin-webpack-bundle-analyzer: ^1.0.5 => 1.0.5
    gatsby-source-filesystem: ^2.1.46 => 2.1.46
    gatsby-source-graphql: ^2.1.32 => 2.1.32
    gatsby-source-shopify: ^3.0.41 => 3.0.41
    gatsby-source-youtube: ^1.0.1 => 1.0.1
    gatsby-transformer-yaml: ^2.2.23 => 2.2.23
  npmGlobalPackages:
    gatsby-cli: 2.8.27
not stale confirmed MDX bug

Most helpful comment

Is there an ETA on the fix for this? It is majorly breaking.

I'm guessing that setting pathPrefix equal to assetPrefix is causing subtle issues elsewhere as well.

Looks like this file is the culprit https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/utils/get-public-path.ts

All 10 comments

Has anyone else experienced this issue? This seems pretty breaking; it makes all linking in mdx files useless when using assetPrefix

Hiya!

This issue has gone quiet. Spooky quiet. 馃懟

We get a lot of issues, so we currently close issues after 30 days of inactivity. It鈥檚 been at least 20 days since the last update here.
If we missed this issue or if you want to keep it open, please reply here. You can also add the label "not stale" to keep this issue open!
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request. Check out gatsby.dev/contribute for more information about opening PRs, triaging issues, and contributing!

Thanks for being a part of the Gatsby community! 馃挭馃挏

This is definitely still an issue, not sure why more people haven鈥檛 experienced it. It鈥檚 possible people don鈥檛 know their mdx links are broken if they鈥檙e using assetPrefix. We got alerted because we鈥檝e programmed a crawler to check our links.

@ZLevine Same here, I didn't realize my MDX links are broken until yesterday, but the assetPrefix change made a month ago 馃槺. Looking for a solution, and I will add some integrated test cases definitely.

Looks like this is the relevant bit of the code

if (pathPrefix) {
    pathPlugin = () =>
      async function transformer(markdownAST) {
        // Ensure relative links include `pathPrefix`
        visit(markdownAST, `link`, node => {
          if (
            node.url &&
            node.url.startsWith(`/`) &&
            !node.url.startsWith(`//`)
          ) {
            // TODO: where does withPathPrefix
            node.url = withPathPrefix(node.url, pathPrefix)
          }
        })
        return markdownAST
      }
  }

So we're not actually setting pathPrefix, only assetPrefix鈥攖hen we use the --prefix-paths flag when building. So for some reason, this plugin thinks pathPrefix is being set and prefixes relative links.

I fixed this issue temporarily.

First, add MDX components to handle custom anchor.
For example:

function MDX({ children }) {
  return <MDXProvider components={{ a: Anchor }}>{children}</MDXProvider>;
}

Second, replace the broken link in Anchor component.

import { useStaticQuery, graphql } from "gatsby";

export default function Anchor(props: AnchorProps) {
  const { children, href, ...otherProps } = props;

  const { site } = useStaticQuery(graphql`
    {
      site {
        assetPrefix
      }
    }
  `);
  let newHref = href;
  const assetPrefix = site.assetPrefix.replace("https://", "https:/");
  if (href.startsWith(assetPrefix)) {
    newHref = href.slice(assetPrefix.length);
  }

  const allProps = { ...otherProps, href: newHref };
  return (
    <a rel="noopener noreferrer" {...allProps}>
      {children}
    </a>
  );
}

Same issue here. It is really a bug. assetPrefix should only affect static assets, not links.

@xsq007 I agree. It seems Gatsby is setting pathPrefix equal to assetPrefix when pathPrefix is not set鈥攖ry outputting pathPrefix during build and it will output the value of assetPrefix instead.

I was hoping that setting pathPrefix equal to an empty string in gatsby-config would provide a workaround but no such luck. Maybe @KyleAMathews knows why pathPrefix always gets set when assetPrefix does.

Is there an ETA on the fix for this? It is majorly breaking.

I'm guessing that setting pathPrefix equal to assetPrefix is causing subtle issues elsewhere as well.

Looks like this file is the culprit https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby/src/utils/get-public-path.ts

This issue is even harder to catch now that you can't run --prefix-paths in develop and this is closed: https://github.com/gatsbyjs/gatsby/issues/3721

Was this page helpful?
0 / 5 - 0 ratings

Related issues

brandonmp picture brandonmp  路  3Comments

rossPatton picture rossPatton  路  3Comments

Oppenheimer1 picture Oppenheimer1  路  3Comments

hobochild picture hobochild  路  3Comments

magicly picture magicly  路  3Comments