Skip to content

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

Closed
@kripod

Description

@kripod

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

Activity

KyleAMathews

KyleAMathews commented on Jan 19, 2018

@KyleAMathews
Contributor

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?

kripod

kripod commented on Jan 19, 2018

@kripod
ContributorAuthor

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

KyleAMathews

KyleAMathews commented on Jan 19, 2018

@KyleAMathews
Contributor

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

kripod

kripod commented on Jan 19, 2018

@kripod
ContributorAuthor

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?

KyleAMathews

KyleAMathews commented on Jan 19, 2018

@KyleAMathews
Contributor

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.

added 2 commits that reference this issue on Jan 19, 2018
01022ab
cdd2efc
added 2 commits that reference this issue on Jan 24, 2018
2eb64d8
c1bfd74
added a commit that references this issue on Mar 6, 2018
652e677
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @KyleAMathews@kripod

        Issue actions

          [gatsby-remark-images] Images with an absolute URL (not a file path) disappear · Issue #3608 · gatsbyjs/gatsby