This is a question and not an issue.
First of all, thanks to the creator and to all the contributors for this awesome project. I recently started working as a freelance and I'm moving to Gatsby for all my static websites project.
I'm trying to recursively importing all the images from a specific folder. Since I'm new to Gatsby and I'm not so skilled in Webpack, my idea was to use the gatsby-source-filesystem to retrieve all the images from a specific folder and then mapping them to my webpage:
const IndexPage = ({ data }) => {
console.log(data);
return (
<div>
<h1>Hi people</h1>
<p>Welcome to your new Gatsby site.</p>
<p>Now go build something great.</p>
{data.allFile.edges.map(img => {
return <img src={withPrefix(`images/${img.node.relativePath}`)} />;
})}
</div>
);
};
export default IndexPage;
export const query = graphql`
query ImagesQuery {
allFile {
edges {
node {
extension
dir
modifiedTime
relativePath
}
}
}
}
`;
As you could imagine, even if I'm successfully retrieving all images' filenames with my query, the <img> element is not able to find the image file to the given path.
Reading the documentation is not helping to reduce the fog I have in my mind and apparently there is not a question like this one... I know I have two possible choices to import images:
The problem with the first solution is that I don't know which files the component should load and there could be something like 400 images to load.
The problem with the second solution is that... I can't make it work 🏆
What am I doing wrong? Also, is there some better solution to my code which makes use of the Webpack importing feature?
Thanks!
Hi! I think I can help. Just to be clear, you want to import all images in a folder, correct? If so, I use the following code for importing _all_ my SVG's from a folder.
var req = require.context("../path/to/my/directory", false, /.*\.svg$/);
req.keys().forEach(function(key){
req(key);
});
Obviously, if you're not using SVG's, replace the /.*\.svg$/ with whatever file type you're using.
Hello and thanks for the comment!
Where should I write that piece of code? In my component?
Thanks!
Me personally, in my layouts/index.js, I call it in the componentDidMount() function.
componentDidMount() {
var req = require.context("../path/to/my/directory", false, /.*\.svg$/);
req.keys().forEach(function(key){
req(key);
});
}
Though I don't know if thats the best place to put it. Maybe in your html.js would be a better place? I'm not exactly sure of the best practice in this scenario.
Have you looked at gatsby-image?
This will take care that the image is copied to the output in public/ and can also perform all kinds of optimizations.
Thanks again for the comment. Below my code:
class IndexPage extends React.Component {
componentDidMount() {
var req = require.context('../../public/static/images', false, /.*\.jpg$/);
req.keys().forEach(function(key) {
req(key);
});
}
render() {
const data = this.props.data;
return (
<div>
<h1>Hi people</h1>
<p>Welcome to your new Gatsby site.</p>
<p>Now go build something great.</p>
<Link to="/page-2/">Go to page 2</Link>
{data.allFile.edges.map((img, index) => {
return (
<img
key={index}
src={withPrefix(`images/${img.node.relativePath}`)}
/>
);
})}
</div>
);
}
}
Now Webpack it's complaining and returning this warning message when he tries to import the image:
warning in ./src/images/DSC02887.JPG
Module parse failed: [...]/src/images/DSC02887.JPG Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type.
It seems like he wants an appropriate loader for the JPG file...
@zionis137 Thanks I'm going to check right now
var req = require.context('../../public/static/images', false, /.*\.jpg$/);
If you put your images in the static/ directory they will be copied directly to public/ and not public/static/.
The public/static/ directory also exists, mostly plugins put stuff there with a hash in the filename.
If I edit it to var req = require.context('/public/', false, /.*\.jpg$/) I get the following error:
ERROR Failed to compile with 1 errors 16:11:11
This dependency was not found:
* /public/images in ./src/pages/index.js
To install it, you can run: npm install --save /public/images
If, instead, I use the relative path: var req = require.context('../../public/static/images', false, /.*\.jpg$/) I'm still having the 404 not found error.
Look at gatsby-image. It really is the better way :smile:
I'm looking at it. As far as I understand it's not solving the problem with the upload of all the bunch of images I have in my folder but it's "just overlaying" a React Component on the <img> element with useful props for managing and optimizing images. Am I wrong?
Seriously... I'm such in a thick fog right now! Why can't I find anyone who has the same problem as me 😞
I made a demo here: https://github.com/zionis137/gatsby-all-image
This takes all images in data/ and displays them on the homepage
Thanks for the demo! It's exactly what I was looking for!
I'm still wondering why it's not working without the gatsby-image plugin. But I think I'll not complain too much 😝
Thanks!
@Lc0rE yeah the relativePath is just the relative path from the root of your gatsby-source-filesystem setup to where the file is at. That won't give you a path you can use.
You'll want to add gatsby-plugin-sharp and gatsby-transformer-sharp so you can query just the images + transform the images to get image thumbnails of the right size.
Check out also the using-gatsby-image example site https://github.com/gatsbyjs/gatsby/tree/master/examples/using-gatsby-image
Going to close this as the original question seems to have been answered :)
@KyleAMathews surely you did an amazing work and I'm here to congratulate you! I'd wish to have a bit more experience to be able to properly contribute to this amazing project.
By the way, I'm still wondering how I could use gatsby-image with something like Bootstrap Carousel.
I mean, components like Carousels are composed like this:
import React from 'react';
import { UncontrolledCarousel } from 'reactstrap';
const items = [
{
src: 'url/to/image/myImage.jpg',
altText: 'Slide 1',
caption: 'Slide 1'
},
{
src: 'url/to/image/myImage.jpg',
altText: 'Slide 2',
caption: 'Slide 2'
},
{
src: 'url/to/image/myImage.jpg',
altText: 'Slide 3',
caption: 'Slide 3'
}
];
const Example = () => <UncontrolledCarousel items={items} />;
export default Example;
As you can see, this component is expecting me to put a path to my image. Now, I surely can require the single images because I've not the scalability problem since a Carousel should contain just a bunch of images. But how should I behave if I want to use the path instead?
I'm actually trying to do the same thing right now and I had no issues with jpgs using the sharp plugins. But I have some animated gifs that aren't exported. Any advice?
@Lc0rE I don't think you would use gatsby-image with bootstrap carousel. You would just need to use one of the sources from your graphql query. Or you could try another carousel that's more idiomatic to react. I usually use https://github.com/FormidableLabs/nuka-carousel. It's not perfect but pretty good.
There is an issue with require.context(). It duplicates the context across chunks that use it.
https://github.com/gatsbyjs/gatsby/issues/6372#issuecomment-581155819
Most helpful comment
Hi! I think I can help. Just to be clear, you want to import all images in a folder, correct? If so, I use the following code for importing _all_ my SVG's from a folder.
Obviously, if you're not using SVG's, replace the
/.*\.svg$/with whatever file type you're using.