1

I have a question about Gatsby, specifically about how to import images if I'm using a JS object because I'm passing it through a prop (look at code-column n°1, literal object in N°2) in the 3rd column is the whole component with all the object being called.

In Gatsby's documentation say that we need to import the img or SVG on top of the component but in this case, I can't. enter image description here

Also, I have tried adding a src={require(img)} in the component but still not working, even when I use an auto-complete path Visual Studio Code extension: enter image description here

Thanks in advance!

Code:

Column One heroSection.js. I pass a image through a prop because I need to use the component a lot of times, just can't put only one image without props:

import React from 'react';
import { Spring } from 'react-spring/renderprops';
import './heroSection.css';
import { Button } from './button';
import { Link } from 'gatsby';

export default function HeroSection({
  lightBg,
  topLine,
  lightText,
  lightTextDesc,
  headline,
  description,
  buttonLabel,
  img,
  alt,
  imgStart
}) {
  return (
    <>
      {/* Background Color */}
      <div className={lightBg ? 'home__hero-section' : 'home__hero-section darkBg'}>
        
      {/* Container: Row & Column */}
        <div className='container'>
          <div className='row home__hero-row'
            style={{
              display: 'flex',
              flexDirection: imgStart === 'start' ? 'row-reverse' : 'row'
            }}
          >
            {/* Column */}
            <div className='col'>
              {/* Toplin & Header */}
              <div className='home__hero-text-wrapper'>

                <Spring from={{ opacity:0 }} to={{ opacity:1 }} config={{ delay: 900, duration: 1100 }} >
                  {props => (
                    <div style={props}>
                      <div className='top-line'>{topLine}</div>
                      <h1 className={lightText ? 'heading' : 'heading dark'}>
                        {headline}
                      </h1>
                      {/* Description */}
                      <p className={ lightTextDesc ? 'home__hero-subtitle' : 'home__hero-subtitle dark' }>
                        {description}
                      </p>
                      {/* Button */}
                      <Link to='/sign-up'>
                        <Button buttonStyle='btn--ghost' buttonColor='scarlet' buttonSize='btn--wide' >
                          {buttonLabel}
                        </Button>
                      </Link>
                    </div>
                  )}
                </Spring>

              </div>
              
            </div>

            {/* Image */}
            <div className='col'>
              <div className='home__hero-img-wrapper'>
                <img src={img} alt={alt} className='home__hero-img' loading="lazy"/>
              </div>
            </div>

          </div>
        </div>

      </div>
    </>
  );
}

Column 2 indexData.js JS objects with the data I will pass on to the properties of component (column 1).

export const tecnologia = {
  lightBg: false,
  lightText: true,
  lightTextDesc: true,
  topLine: 'Tecnología y Ambiente',
  headline: 'Horticultura urbana tecnológica para todos',
  description:
    'Nuestro sofware te acesora, supervisa y mejora tus cultivos urbanos además de ser altamente soportada por la comunidad por su código abierto.',
  buttonLabel: '¡Empieza Ahora!',
  imgStart: 'start',
  img: '/src/images/environment.svg',
  alt: 'Environment'
};

export const comunidad = {
  lightBg: true,
  lightText: false,
  lightTextDesc: false,
  topLine: 'Amado por la comunidad',
  headline: 'El software es atendido por la comunidad',
  description:
    "Sin importar el tipo de cultivo, la comunidad aporta semanalmente grandes cambios y variaciones d nustro software modular para hacer más amplio la cartera de plantas que el usuario podrá cultivar sin procuparse.",
  buttonLabel: 'Abrir Repositorio',
  imgStart: '',
  img: '../images/programmer.svg',
  alt: 'Programmer'
};


export const seguridad = {
  lightBg: false,
  lightText: true,
  lightTextDesc: true,
  topLine: '100% Seguro',
  headline: 'Protegemos tus datos',
  description:
    '¡Confía en nosotros! No vendemos tus datos sensibles a terceros, la seguridad y confianza es menester para nuestro producto',
  buttonLabel: 'Leer Políticas',
  imgStart: 'start',
  img: '../images/sec.svg',
  alt: 'Seguridad'
};

export const estadistica = {
  lightBg: false,
  lightText: true,
  lightTextDesc: true,
  topLine: 'Ciencia De Datos',
  headline: 'Ofrecemos estadísticas de tus cosechas para mejorarlas',
  description:
    'Analizamos los datos para ofrecer un mejor servicio y los abrimos anónimamente a la comunidad, para así enfocarnos en una mejor experiencia de usuario, cosechas más fértiles y ahorro de tiempo.',
  buttonLabel: 'Registrate Ahora',
  imgStart: '',
  img: '../images/data.svg',
  alt: 'Data'
};

Column 3 index.js, also knows as a Home or IndexPage. Here is the component being used many times.

import React from "react";
import './index.css';
import Layout from './../components/layout';
import HeroSection from './../components/heroSection';
import { tecnologia, comunidad, seguridad, estadistica } from './indexData.js';

export default function IndexPage() {
  return (
    <Layout>
      <HeroSection {...tecnologia} />
      <HeroSection {...comunidad} />
      <HeroSection {...seguridad} />
      <HeroSection {...estadistica} />
    </Layout>
  )
}
Arghavan
  • 1,125
  • 1
  • 11
  • 17
RicardoRien
  • 41
  • 2
  • 5

1 Answers1

1

You don't need to import an image in the top-level components. You can import it wherever you want and use it in multiple ways.


Disclaimer: if you are dealing with SVG I would recommend the following SO answer.


If your images are inside the filesystem of Gatsby, you can query them via GraphQL and use gatsby-image.

If don't, just import the asset directly in your component:

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

P.S: please provide a code sample rather than images.


The solution was using the import like this inside indexData:

import a from '../images/a.svg';
const obj = { img: a }
Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67
  • Thanks for your comment but i need to pass the SVG as a props because a I need to use the multiple time, with diferents SVG. I been trying link this but doesn't work ``` ``` Gives me an error in the console. I already put the code in the question. Thanks – RicardoRien Oct 31 '20 at 20:17
  • 1
    You can pass as well as an image, itself, an image path or a SVG component (check the provided link) to be rendered in a child component. Make sure that your image is showing before passing it downside. – Ferran Buireu Oct 31 '20 at 21:24
  • Finally! It works! i was using curly braces inside the Object in IndexData insted the regular name chosed: ``` import a from '../images/a.svg'; const obj = { img: a } ``` Thank for your time. I have a lot of thing to learn. – RicardoRien Oct 31 '20 at 22:17
  • I'm glad to help, I've updated the answer with the solution.. If the issue has been solved please accept the answer to close the issue. – Ferran Buireu Nov 01 '20 at 07:11