Gatsby: [gatsby-remark-images] Images with an absolute URL (not a file path) disappear

Created on 19 Jan 2018  Â·  5Comments  Â·  Source: gatsbyjs/gatsby

Description

When I try to load an image through an URL from a markdown file with gatsby-remark-images, the image just disappears. No image-related code makes it into the final, statically rendered HTML files.

Environment

Gatsby version: 1.9.160
Node.js version: 8.9.3
Operating System: Windows 10 x64

File contents (if changed):

gatsby-config.js:

const { siteMetadata } = require('./site-settings.json');

module.exports = {
  siteMetadata,
  plugins: [
    'gatsby-plugin-catch-links',
    'gatsby-plugin-glamor',
    'gatsby-plugin-jss',
    'gatsby-plugin-react-helmet',
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'static/assets',
        path: `${__dirname}/static/assets`,
      },
    },
    {
      resolve: 'gatsby-source-filesystem',
      options: {
        name: 'src',
        path: `${__dirname}/src/`,
      },
    },
    {
      resolve: 'gatsby-transformer-remark',
      options: {
        plugins: [
          'gatsby-plugin-sharp',
          'gatsby-remark-copy-linked-files',
          {
            resolve: 'gatsby-remark-images',
            options: {
              maxWidth: 640,
            },
          },
          'gatsby-remark-responsive-iframe',
          {
            resolve: 'gatsby-remark-smartypants',
            options: {
              dashes: 'oldschool',
            },
          },
        ],
      },
    },
    'gatsby-transformer-sharp',
  ],
};

package.json:

{
  "private": true,
  "scripts": {
    "build": "gatsby build",
    "develop": "gatsby develop",
    "lint": "eslint \"src/**/*.{js,jsx}\"",
    "format": "prettier-eslint --write \"src/**/*.{js,jsx}\""
  },
  "dependencies": {
    "fs-extra": "^4.0.2",
    "gatsby": "^1.9.118",
    "gatsby-link": "^1.6.15",
    "gatsby-plugin-catch-links": "^1.0.8",
    "gatsby-plugin-glamor": "^1.6.7",
    "gatsby-plugin-jss": "^1.5.6",
    "gatsby-plugin-react-helmet": "^2.0.1",
    "gatsby-plugin-sharp": "^1.6.25",
    "gatsby-remark-copy-linked-files": "^1.5.7",
    "gatsby-remark-images": "^1.5.11",
    "gatsby-remark-responsive-iframe": "^1.4.7",
    "gatsby-remark-smartypants": "^1.4.7",
    "gatsby-source-filesystem": "^1.4.12",
    "gatsby-transformer-remark": "^1.7.7",
    "gatsby-transformer-sharp": "^1.6.5",
    "material-ui": "^1.0.0-beta.16",
    "moment": "^2.18.1",
    "normalize.css": "^7.0.0",
    "react-big-calendar": "^0.17.0",
    "react-headroom": "^2.1.6",
    "react-helmet": "^5.2.0",
    "react-icons": "^2.2.5",
    "react-images": "^0.5.11",
    "react-photo-gallery": "^6.0.15"
  },
  "devDependencies": {
    "babel-eslint": "^8.0.0",
    "eslint": "^4.6.0",
    "eslint-config-airbnb": "^16.0.0",
    "eslint-plugin-import": "^2.7.0",
    "eslint-plugin-jsx-a11y": "^6.0.2",
    "eslint-plugin-react": "^7.3.0",
    "prettier-eslint": "^8.1.0",
    "prettier-eslint-cli": "^4.3.0"
  }
}

gatsby-node.js:

const path = require('path');
const { createFilePath } = require('gatsby-source-filesystem');

exports.onCreateNode = ({
  node, getNode, getNodes, boundActionCreators,
}) => {
  const { createNodeField, createParentChildLink } = boundActionCreators;

  if (node.internal.type === 'MarkdownRemark') {
    const slug = createFilePath({ node, getNode, basePath: 'pages' });
    createNodeField({
      node,
      name: 'slug',
      value: slug,
    });

    // Attach thumbnail's ImageSharp node by public path if necessary
    if (typeof node.frontmatter.thumbnail === 'string') {
      // Find absolute path of linked path
      const pathToFile = path
        .join(__dirname, 'static', node.frontmatter.thumbnail)
        .split(path.sep)
        .join('/');

      // Find ID of File node
      const fileNode = getNodes().find(n => n.absolutePath === pathToFile);

      if (fileNode != null) {
        // Find ImageSharp node corresponding to the File node
        const imageSharpNodeId = fileNode.children.find(n => n.endsWith('>> ImageSharp'));
        const imageSharpNode = getNodes().find(n => n.id === imageSharpNodeId);

        // Add ImageSharp node as child
        createParentChildLink({ parent: node, child: imageSharpNode });
      }
    }
  }
};

exports.createPages = ({ graphql, boundActionCreators }) => {
  const { createPage } = boundActionCreators;

  return new Promise((resolve) => {
    graphql(`
      {
        allMarkdownRemark {
          edges {
            node {
              fields {
                slug
              }
            }
          }
        }
      }
    `).then(({ data }) => {
      data.allMarkdownRemark.edges.forEach(({ node }) => {
        createPage({
          path: node.fields.slug,
          component: node.fields.slug.startsWith('/gallery/')
            ? path.resolve('./src/templates/album.jsx')
            : path.resolve('./src/templates/blog-post.jsx'),
          context: {
            // Data passed to context is available in page queries as GraphQL variables
            slug: node.fields.slug,
          },
        });
      });

      resolve();
    });
  });
};

Steps to reproduce

1. Add ![alt](/assets/uploads/image.jpg) to a markdown file, where /assets/uploads/image.jpg is hosted at the appropriate URL. _(See this file for an example.)_

2. Run gatsby develop

3. Navigate to the markdown file's corresponding page

All 5 comments

Hmm yeah, doesn't look we account for this.

So these are files you're adding to the static directory?

I think a check for absolute paths added to https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-remark-images/src/index.js would fix this. Could you add a PR?

Yes, I'm serving those images from the static directory, and I'll try my best to do a PR soon.

awesome! Reach out if you need any help :-)

I'm a bit confused about how this should be implemented. I think that we may come across a solution by:

  • Enforcing that file-based paths shall start with . _(this includes ..)_. This would break backwards-compatibility.
  • Checking whether a file exists in the file system at the given location. If not, then we should assume that an URL-based path was given. This would make the build process a bit slower.

I would personally go with the second option, what do you think?

Yeah, definitely #2 — good point that an absolute path check is breaking/flaky. If we can't find the linked image, we should just quit gracefully and leave things as they are.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mikestopcontinues picture mikestopcontinues  Â·  3Comments

brandonmp picture brandonmp  Â·  3Comments

signalwerk picture signalwerk  Â·  3Comments

benstr picture benstr  Â·  3Comments

totsteps picture totsteps  Â·  3Comments