0

This is for the front page.

I've made an image collection in gridsome.server.js by scanning a folder full of images and creating nodes, each containing the name and the path of the image:

    let dir = fs.opendirSync(process.cwd() + '/static/images')
    let fd, fn, nameParts
    const imagesColl = actions.addCollection('images')
    while (!!(fd = dir.readSync())) {
      fn = fd.name
      nameParts = fn.split('.')
      imagesColl.addNode({
        name: nameParts[0],
        path: '/images/' + fn
      })
    }

    dir.close()

In the title page, I'm creating a 4x2 grid of these images.

The graphql query looks like this:

  images:allImages {
    edges {
      node {
        name
        path
      }
    }
  }

and then in my vue page component, I'm using the images like this

...
  <div>
      <div class="grid grid-cols-4 shadow-xl">
      <g-image width="100" v-for="(edge, ix) of $page.images.edges" :key="ix"
           :src="edge.node.path" />
    </div>
  </div>

So, the collection is being created just fine, I'm able to query them in the page, but It doesn't seem like the g-image processor is getting invoked at all.

I'm specifying a width of "100", which I expect to see a grid of smallish images - but it's not happening. Basically the resulting output is just the browser sizing them down to "dumbnails" about 300px across (for this page size.)

Any thoughts appreciated.

rickb
  • 601
  • 5
  • 19

1 Answers1

1

This is a documented bug in gridsome. This comment gives a workaround for a way to fix this. I've tested this solution and it has worked for me. Copying it here directly:

Go to gridsome.config.js and add an alias for your images folder inside of the chainWebpack function (you may need to add it):

module.exports = {
  siteName: 'Jeremy Jackson',
  plugins: [],
  chainWebpack: config => {
    config.resolve.alias.set('@images', '@/assets/images')
  },
  templates: {}
}

Save the file and restart the server. Then in your code where you want to use the image you can do:

<g-image :src="require(`!!assets-loader!@images/${imageUrl}`)"/>

And the dynamic image shows up. This works inside of v-for as well. For reference, here's the code I'm using inside of a v-for in my site:

<div id="project-images">
  <div class="section-header">Screenshots</div>
  <div class="row">
    <div 
      class="col-xs-12 col-sm-3 project-image"
      v-for="(projectImage, index) in $page.project.images"
      :key="projectImage"
      @click="openLightBox(index)"
    >
      <g-image class="responsive-image" :src="require(`!!assets-loader!@images/${projectImage}`)"/>
    </div>
  </div>
</div>

Width and Height don't work with this method, here's the workaround for that:

to specify a width/height/etc you add a query string right before the path. So the example above would become:

<g-image class="responsive-image" :src="require(`!!assets-loader?width=250&height=250!@images/${projectImage}`)"/>
TheRobotCarlson
  • 346
  • 1
  • 7