datocms / gatsby-source-datocms

Official GatsbyJS source plugin to pull content from DatoCMS
MIT License
140 stars 50 forks source link

causes an error when used with local MDX files and `createNodeField` #106

Closed endymion1818 closed 4 years ago

endymion1818 commented 4 years ago

I have a Gatsby site which I'm integrating with DatoCMS. The site also sources from local MDX files.

When I add gatsby-plugin-datocms, the following error is generated on running gatsby build:

success loading DatoCMS content - 1.033s

 ERROR #11321  PLUGIN

"gatsby-node.js" threw an error while running the onCreateNode lifecycle:

Cannot read property 'replace' of undefined

  12 |       name: 'slug',
  13 |       node,
> 14 |       value: createFilePath({
     |              ^
  15 |         node,
  16 |         getNode,
  17 |         basePath: 'pages',

File: gatsby-node.js:14:14

The other thing of note is that I have some custom nodes being created in gatsby-node.js:

const createMdxNodeFields = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type.toLowerCase() === 'mdx') {
    createNodeField({
      name: 'slug',
      node,
      value: createFilePath({
        node,
        getNode,
        basePath: 'pages',
      }),
    })
  }
}
exports.onCreateNode = createMdxNodeFields
endymion1818 commented 4 years ago

I'm currently investigating whether there is a different way to locate my mdx pages that would isolate them from content pulled in from DatoCMS.

matjack1 commented 4 years ago

@endymion1818 are you saying that the source plugin alone works fine, but in conjuction of MDX files it gives you these errors?

Can you maybe share your gatsby-config file so that I can try reproducing?

endymion1818 commented 4 years ago

hi @matjack1, here's what I can share:

require('dotenv').config()

module.exports = {
  siteMetadata: {
    title: 'xxxx.com',
    siteUrl: process.env.GATSBY_APP_URL,
  },
  plugins: [
    {
      resolve: 'gatsby-plugin-google-tagmanager',
      options: {
        id: 'GTM-XXXXXX',
      },
    },
    {
      resolve: `gatsby-plugin-google-analytics`,
      options: {
        trackingId: 'UA-XXXXXX-1',
        head: true,
        anonymize: true,
        respectDNT: true,
      },
    },
    'gatsby-plugin-remove-serviceworker',
    'gatsby-plugin-react-helmet',
    'gatsby-plugin-typescript',
    'gatsby-plugin-remove-trailing-slashes',
    'gatsby-transformer-sharp',
    {
      resolve: 'gatsby-plugin-sharp',
      options: {
        useMozJpeg: false,
        webpQuality: 100,
        stripMetadata: true,
        defaultQuality: 80,
      },
    },
    {
      resolve: 'gatsby-plugin-web-font-loader',
      options: {
        google: {
          families: ['Open Sans:400,600,700&display=swap'],
        },
      },
    },
    {
      resolve: 'gatsby-plugin-styled-components',
      options: {
        displayName: true,
      },
    },
    {
      resolve: 'gatsby-plugin-robots-txt',
      options: {
        host: process.env.GATSBY_APP_URL,
        sitemap: `${process.env.GATSBY_APP_URL}/sitemap.xml`,
        resolveEnv: () => process.env.GATSBY_ACTIVE_ENV || 'production',
        env: {
          sandbox: {
            policy: [{ userAgent: '*', disallow: ['/'] }],
          },
          uat: {
            policy: [{ userAgent: '*', disallow: ['/'] }],
          },
          production: {
            policy: [{ userAgent: '*', allow: '/' }],
          },
        },
      },
    },
    {
      resolve: 'gatsby-plugin-sitemap',
      options: {
        exclude: [
          '/errors/*',
          '/support/oops',
          '/support/thanks',
        ],
      },
    },
    {
      resolve: 'xxxx-source-xxxx',
      options: {
        url: 'https://xxxx.xxxx.xxxx.com/SiteMessage/services/xml/SiteMessages',
      },
    },
    {
      resolve: 'xxxx-source-trustpilot',
      options: {
        apiKey: process.env.TRUST_PILOT_API_KEY,
        secretKey: process.env.TRUST_PILOT_SECRET_KEY,
        username: process.env.TRUST_PILOT_USERNAME,
        password: process.env.TRUST_PILOT_PASSWORD,
        domains: ['xxxx.com'],
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        path: `${__dirname}/src/assets/images/`,
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'pages',
        path: `${__dirname}/src/pages/`,
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'awards',
        path: `${__dirname}/data/awards/`,
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'presenters',
        path: `${__dirname}/data/presenters/`,
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'quotes',
        path: `${__dirname}/data/quotes/`,
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'people',
        path: `${__dirname}/data/people/`,
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'knowledgebase',
        path: `${__dirname}/data/knowledgebase/`,
      },
    },
    'gatsby-transformer-javascript-frontmatter',
    {
      resolve: 'gatsby-source-apiserver',
      options: {
        typePrefix: 'xxxx__',
        url: `${process.env.GATSBY_XXXX_SERVICE_URL}/api/xxxx`,
        method: 'get',
        headers: {
          'Content-Type': 'application/json',
        },
        name: 'xxxxData',
        entityLevel: 'xxxxData',
        auth: null,
        localSave: true,
        path: `${__dirname}/data/content/`,
        skipCreateNode: true,
      },
    },
    {
      resolve: 'gatsby-source-apiserver',
      options: {
        typePrefix: 'xxxx__',
        url: `${process.env.GATSBY_XXXX_SERVICE_URL}/api/apr-range`,
        method: 'get',
        headers: {
          'Content-Type': 'application/json',
        },
        name: 'aprRange',
        auth: null,
        skipCreateNode: false,
      },
    },
    {
      resolve: 'gatsby-source-apiserver',
      options: {
        typePrefix: 'xxxx__',
        url: `${process.env.GATSBY_XXXX_SERVICE_URL}/api/rep-price?amount=10000&term=60`,
        method: 'get',
        headers: {
          'Content-Type': 'application/json',
        },
        name: 'repprice',
        auth: null,
        localSave: true,
        path: `${__dirname}/data/content/`,
        skipCreateNode: false,
      },
    },
    {
      resolve: 'gatsby-source-apiserver',
      options: {
        typePrefix: 'xxxx__',
        url: `${process.env.GATSBY_XXXX_SERVICE_URL}/api/rep-price?amount=10000&term=60&channel=xxxx`,
        method: 'get',
        headers: {
          'Content-Type': 'application/json',
        },
        name: 'xxxx',
        auth: null,
        localSave: true,
        path: `${__dirname}/data/content/`,
        skipCreateNode: false,
      },
    },
    {
      resolve: 'xxxx-source-wordpress',
      options: {
        domain: 'https://blog.zopa.com/',
        categories: ['664'],
      },
    },
    'xxxx-source-lever',
    {
      resolve: 'gatsby-plugin-mdx',
      options: {
        name: 'localPages',
        defaultLayouts: {
          default: require.resolve('./src/components/Templates/Markdown.tsx'),
        },
      },
    },
    'gatsby-plugin-react-helmet',
    {
      resolve: 'gatsby-plugin-react-helmet-canonical-urls',
      options: {
        siteUrl: process.env.GATSBY_APP_URL,
        noTrailingSlash: true,
      },
    },
    {
      resolve: `gatsby-source-datocms`,
      options: {
        apiToken: process.env.DATOCMS_TOKEN,
      },
    },
    `gatsby-transformer-remark`,
  ],
}
endymion1818 commented 4 years ago

I'm also working on a POC for this error with the default Gatsby starter

endymion1818 commented 4 years ago

Here's a working example of this issue: https://github.com/endymion1818/datocmstest

matjack1 commented 4 years ago

thank you so much @endymion1818 we'll be in touch as soon as possible!

endymion1818 commented 4 years ago

We resolved this yesterday, I’ll post details here soon.

endymion1818 commented 4 years ago

Fix was to check for a fileAbsolutePath on the node:

if (node.internal.type.toLowerCase() === 'mdx' && node.fileAbsolutePath) {
}
matjack1 commented 4 years ago

thank you very much @endymion1818 for following this up with your solution!