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;
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 asindex.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