0

Sorry if there's a really simple solution, but building websites isn't my area of expertise.

I'm currently trying to create a Gatsby website where I have a Component nestled inside another Component but it shows a completely blank screen when I try to show the nestled Component. Following the answer from this question, I implemented a Layout Component that serves as a template for every site. In the future, I plan to tidy up the navigation bar and implement that into the Layout Component, but that's an issue for another time.

I'm currently trying to put in a Tile Component into my Layout that is also encapsulated inside my IndexPage, but my screen just shows nothing when I try to run it. I've tried to shorten the code so that it includes the minimum amount required.

I've taken a look at the Gatsby documentation and it appears that under the "Non-page components" section that I should use GraphQL, which I'm not sure how it works.

I suspect that the reason why it isn't working is that the Tile Component has to take in an imgLocation, altText, and caption properties, and somewhere along the way the code isn't working as intended.


Code:

index.js:

import * as React from "react"
import Layout from './Layout.js';
import Tile from './Tile.js';

// markup
const IndexPage = () => {

    return (
        <Layout pageTitle="Home">
                <div id="main">
                    <div className="inner">
                        <h1>
                            <b>Portfolio</b>
                        </h1>
                        <p>
                            Here's all of the work that I've been commissioned to do over the past few years.
                        </p>
                        <h2>
                            <b>Christmas</b>
                        </h2>
                        <h3>
                            <b>Portrait</b>
                        </h3>
                        <section className="tiles">
                            <Tile imgLocation="imageFileLocationGoesHere" altText="descriptionOfImage" caption="Image Description" />
                            <Tile imgLocation="imageFileLocationGoesHere" altText="descriptionOfImage" caption="Image Description" />
                        </section>
                        <br />
                        <h3>
                            <b>Landscape</b>
                        </h3>
                        <section className="tiles">
                            <Tile imgLocation="imageFileLocationGoesHere" altText="descriptionOfImage" caption="Image Description" />
                            <Tile imgLocation="imageFileLocationGoesHere" altText="descriptionOfImage" caption="Image Description" />
                        </section>
                    </div>
                </div>
                {/* Footer */}
                <footer id="footer">
                    {/* footer goes here */}
                </footer>
        </Layout>
    )
}

export default IndexPage;

Tile.js (within the same folder as index.js):

import React from "react";
import '../css/main.css';

const Tile = (props) => {
    const imgLocation = props.imgLocation;
    const altText = props.altText;
    const caption = props.caption;

    return (
        <article>
            <span>
                <img src={require({imgLocation}).default} alt={altText} onClick={() => {openModal(props)}} />
            </span>
            <br />
            <p>{caption}</p>
        </article>
    );
}

export default Tile;

Layout.js (within the same folder as in index.js)

import * as React from 'react';

const Layout = ({pageTitle, children}) => {
    return (
        <main>
                <title>{pageTitle}</title>
                <meta charSet="utf-8" />
                <meta
                    name="viewport"
                    content="width=device-width, initial-scale=1, user-scalable=no"
                />
                {children}
        </main>
    )
}

export default Layout;
PerplexingParadox
  • 1,196
  • 1
  • 7
  • 26
  • "...but it shows a completely blank screen when I try to show the nestled Component" - is there an error in the console? Do you do anything before it shows a blank page? Please elaborate. – Brendan Bond Jan 02 '22 at 03:24
  • @Brendan Bond In the console there are multiple errors that say, "Uncaught Error: Cannot find module '[object Object]'". Let me know if you want more info. It's happening in the Tile.js file, specifically where I use the `img` object. – PerplexingParadox Jan 02 '22 at 03:30
  • Ha yes, more info is definitely needed. What line is the error throwing on? What's up with the src attribute in the image tag having a `require` function? You're also passing the string `"imageFileLocationGoesHere"` as a prop? Lots of problems here, this is why people typically ask for a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example), there's just too much going on here to try and help without a lot more context. – Brendan Bond Jan 02 '22 at 03:35
  • Yes, OK, let's start there (your most recent comment edit). Why do you have `require({imgLocation}).default` as the src attribute in that img tag? – Brendan Bond Jan 02 '22 at 03:36
  • @Brendan Bond I have multiple different images, so depending on what is passed in the `imgLocation`, I want to be able to find it there. Oh, and `"imageFileLocationGoesHere"` isn't the actual string being used, in reality it would actually be an actual location like "./images/img.png". – PerplexingParadox Jan 02 '22 at 14:30

1 Answers1

1

The problem you are facing here is that your Tile component is inside the /pages folder as you pointed here:

Tile.js (within the same folder as index.js):

So, Gatsby is trying to create a page based on the Tile component, hence, you are trying to render a page inside a page.

Move your component into another folder such as src/components/Tile and the issue should be gone.

Layout component also needs to be outside /pages folder.

Regarding the image, try to import it in the parent component and lift it to the child like:

import * as React from "react"
import Layout from './Layout.js';
import Tile from './Tile.js';

... 

<Tile imgLocation={'./path/to/your/image.png'} />

And then:

  <img src={imgLocation} alt={altText} onClick={() => {openModal(props)}} />

Or even drilling the image directly:

    import Img from './path/to/your/image.png'

   ...

    <Tile img={Img} />

Then:

const Tile = ({img:Img, altText, caption}) => {

    return (
        <article>
            <span>
            <Img />
            </span>
            <br />
            <p>{caption}</p>
        </article>
    );
}

export default Tile;

Reassigning the img props as React component should also do the trick

Ferran Buireu
  • 28,630
  • 6
  • 39
  • 67
  • So I did that and it still gave me the "Uncaught Error: Cannot find module '[object Object]". – PerplexingParadox Jan 02 '22 at 14:28
  • Try removing CSS modules (to see if the issue is there). They need to be imported namely https://stackoverflow.com/questions/66869576/gatsby-warn-attempted-import-error-css-does-not-contain-a-default-export-i/66869722#66869722 – Ferran Buireu Jan 02 '22 at 16:29
  • The problem is that I never use the CSS module in my `Tile` component so it shouldn't affect it at all. I'll probably stylize it later, but that's not what's causing my issue. I even removed the line `import '../css/main.css'` in my Tile.js file and it didn't change. – PerplexingParadox Jan 02 '22 at 16:36
  • `require({imgLocation}).default` that line is weird. Import it as ES module (`import X from '../../imgLocation`) – Ferran Buireu Jan 02 '22 at 16:41
  • The problem is that I can't import it inside of the `Tile` component itself, and I want the `imgLocation` to be a variable so that I can create different `Tile`s with different images. – PerplexingParadox Jan 02 '22 at 16:44
  • Yep, but first you need to fix your blank page, afterwards you can move forward the image importation. Does this fix the blank rendering? I'd try a dynamic import instead a require – Ferran Buireu Jan 02 '22 at 16:46
  • Now I have a Module parse failed: Unexpected character. I've tried doing `var url = require('.../images/test.PNG).default;` as well as directly importing it like `import img from '../images/test.PNG';` like from [this question](https://stackoverflow.com/questions/39458511/how-to-use-es6-import-for-images). It still gives me a blank screen. – PerplexingParadox Jan 02 '22 at 17:19
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/240665/discussion-between-ferran-buireu-and-perplexingparadox). – Ferran Buireu Jan 03 '22 at 05:44