2

How to show images? It can not be shown correctly below.

In the src/components/Header.js file:

<img src="../images/logo.png" style={{width:"112",height:"28"}} />

Snipaste_2019-07-09_18-24-05

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
zwl1619
  • 4,002
  • 14
  • 54
  • 110

2 Answers2

4

Importing Assets Directly Into Files

import React from "react"
import logo from "./logo.png" // Tell Webpack this JS file uses this image

console.log(logo) // /logo.84287d09.png

function Header() {
  // Import result is the URL of your image
  return <img src={logo} alt="Logo" />
}

export default Header

The reason this is best is that it enables optimizations through the Webpack bundling pipeline, e.g. compression, data URLs, cache busting filename hashes, etc.

Using the Static folder

This is mostly useful for files other than images.

You can create a folder named static at the root of your project. Every file you put into that folder will be copied into the public folder. E.g. if you add a file named sun.jpg to the static folder, it’ll be copied to public/sun.jpg

You can reference assets from the static folder in your code without anything special required:

render() {
  // Note: this is an escape hatch and should be used sparingly!
  // Normally we recommend using `import` for getting asset URLs
  // as described in the “Importing Assets Directly Into Files” page.
  return <img src={'logo.png'} alt="Logo" />;
}

Corey's answer quotes the "Add custom webpack config" section of the Gatsby documentation, which is useful but unnecessary to load images.

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
  • On the very page you linked for using the Static folder Gatsby warns against exactly this usage. “When using Gatsby, we recommend Importing Assets Directly in JavaScript files, because of the benefits it provides…”. I would avoid suggesting a beginner start abusing it by providing an example like this. https://www.gatsbyjs.org/docs/static-folder/#when-to-use-the-static-folder – coreyward Jul 09 '19 at 16:24
  • 1
    @coreyward it's even in the comments I quoted and the recommended way is in my answer as well. I don't think it could be clearer. – Emile Bergeron Jul 09 '19 at 17:06
  • 1
    @coreyward I swapped them so the first thing anybody sees is the right way. – Emile Bergeron Jul 09 '19 at 17:29
0

Create a gatsby-node.js file at the root of your project if you don't already have one and add this:

const path = require("path")

exports.onCreateWebpackConfig = ({ stage, actions }) => {
  actions.setWebpackConfig({
    resolve: {
      modules: [path.resolve(__dirname, "src"), "node_modules"],
      alias: { react: path.resolve("./node_modules/react") },
    },
  })
}

This does two things:

  1. It will make src the base for your imports
  2. It will ensure that you don't run into weird bugs due to multiple versions of React getting loaded (plugins that need to reference React can cause this).

In your Header.js file, you can now do this:

import logo from "images/logo.png"

export const Header => 
  <header>
    <img src={logo} alt="Logo Alt Text" />
  </header>

The rendered result of this will actually be different depending on the file size of your logo. If it's small enough, Gatsby will inline it using base64, reducing the number of HTTP requests required to load your page. If it's larger, it will be given an asset fingerprint and added to the assets available when your site is built and the URL to the file will be used for the src attribute (e.g. /images/logo-123asd.png). This will allow you to use HTTP cache headers that tell the browser it's safe to cache this file for a long time; if it changes, the URL will change and you don't need to worry about invalidating the cached version.

coreyward
  • 77,547
  • 20
  • 137
  • 166
  • To avoid ambiguity or confusing imports, it's best to alias the `src` directory (with say `@/`) instead of making it a default import root. – Emile Bergeron Jul 09 '19 at 17:09
  • @EmileBergeron Source? – coreyward Jul 09 '19 at 17:13
  • @EmileBergeron There's even a [Gatsby plugin that does this](https://www.gatsbyjs.org/packages/gatsby-plugin-resolve-src/). – coreyward Jul 09 '19 at 17:16
  • Different tools may fail to load files correctly or it may be confusing (which file was loaded), like sass processors, Jest and/or storybook. It's even better to do the aliasing in babel since it's shared with most tools while they each have their own webpack config. It's also a common standard to go with `@/` for the whatever the source directory is. – Emile Bergeron Jul 09 '19 at 17:21
  • Gatsby orchestrates Sass. I do the same thing w/ Storybook in `.storybook/webpack.config.js`. [babel-plugin-module-resolver](https://www.npmjs.com/package/babel-plugin-module-resolver) sets `./src` as the root for aliases in the examples (w/o aliasing `src`). [babel-plugin-root-import](https://github.com/entwicklerstube/babel-plugin-root-import#custom-rootpathprefix) recommends against using `@`. It also seems to [create a lot of confusion](https://stackoverflow.com/questions/42711175/what-does-the-symbol-do-in-javascript-imports). – coreyward Jul 09 '19 at 18:00
  • I was talking about webpack processing URL within Sass files, not sure how gatsby handle these, but I had problems before. `@something` may look like a npm namespace, but `@/something` or `~/something` won't. The confusion created by the `@` character will be the same for any alias for a newcomer. Both our goal is to avoid confusion, I'm just informing anyone of a widespread standard. – Emile Bergeron Jul 09 '19 at 18:13
  • Re: Sass — changing the module resolution doesn't affect the way sass-loader loads assets; you would still use relative URLs unless you configure something else. Re: aliasing — `~` has another meaning on *nix systems; aliasing it to mean something else is not likely to produce good results. I still don't understand the issue you have adjusting the root; this is the way $PATH works on *nix, and how path resolution works in other languages. I still have yet to see any evidence that aliasing is a “widespread standard”, much less the “best” way to “avoid ambiguity or confusing imports”. – coreyward Jul 09 '19 at 18:22
  • Widespread: `@/` is the default for vue CLI for example, it's even proven as widespread by the very question you linked. Unix and `$PATH` is irrelevant here. _"you would still use relative URL"_ yes but aliases help when you have a global SASS file and the sass loader is easily confused. – Emile Bergeron Jul 09 '19 at 18:29
  • @EmileBergeron Okay, so you're recommending I change my answer dealing with a Gatsby project that has nothing to do with Sass (or even CSS) to match the way that Vue CLI handles Sass imports despite the practice being explicitly discouraged by the project that introduced it in the first place. Thanks for the context, but I'll pass. – coreyward Jul 09 '19 at 18:41
  • I feel like you're trying hard not to understand and it's a shame. Vue CLI is just an example, and I listed more examples that relates to any project using Webpack. It's even better to manage your own aliases (changing an alias, avoiding ambiguity when adding a new directory to aliases, etc.) My initial comment stands for anyone that comes across your answer, not specifically for you. Feel free to ignore it. `¯\_(ツ)_/¯` – Emile Bergeron Jul 09 '19 at 18:54