If you are using create-react-app, and you import images into your JS files, those images will be loaded using the url-loader webpack module (link to its github), which either embeds your images directly into the HTML using DataURLs (more on that here) or the images are put into their own separate file if they are bigger than 10,000 bytes.
The relevant code is in webpack.config.prod.js:
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve('url-loader'),
options: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]',
},
},
Per the configuration above, larger images (above 10,000 bytes) will be placed in the static/media folder.
This is the behavior if you import your images into your JS files like below:
import img from './file.png'
If you are not importing your images, then it is completely up to you to choose how organize your images. For example, you could place your images in a /static/images folder in your root directory, and reference those images like so:
<img src="/static/images/logo.png" />
In terms of best practice, you can make an argument either way. One key benefit of using url-loader is that smaller images are embedded into your HTML, which should help with performance. On the other hand, serving your images from a CDN can potentially serve your large images faster than your application's server.