Graphql query does not return image for gatsby-image but works in graphiQL - graphql

I am building a blog with multiple gatsby-source-filesystem instances.
I am trying to use gatsby-image on a page but it simply returns:
TypeError: Cannot read property 'fixed' of undefined
The image I'm trying to query is located at src/images
spirits.js
import React from "react"
import { graphql } from "gatsby"
import Img from 'gatsby-image'
import Layout from "../components/layout"
import SEO from "../components/seo"
import Paper from '../components/paper'
const SpiritsPage = ({data}) => (
<Layout>
<SEO title="Spirits" />
<Paper>
<h1>Spirits</h1>
<p>This section is still under construction.</p>
<Img fixed={data.allImageSharp.edges.node.fixed} alt />
</Paper>
</Layout>
)
export const query = graphql`
query {
allImageSharp(filter: {fluid: {originalName: {eq: "australia.png"}}}) {
edges {
node {
fixed {
...GatsbyImageSharpFixed
}
}
}
}
}
`
export default SpiritsPage
gatsby-config.js
{
resolve: `gatsby-source-filesystem`,
options: {
name: `distilleries`,
path: `${__dirname}/content/distilleries`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `posts`,
path: `${__dirname}/content/posts`
},
},
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,

data.alImageSharp.edges is an array, so you can't do data.allImageSharp.edges.node. Instead, what you need to do is grab the item you want from the edges array and then do node.fixed on it. Something like the following would work: data.allImageSharp.edges[0].node.fixed
credit – goto1

Related

Gatsby MDX Graph QL Queries not displaying my posts?

So it's been a while since I updated my Gatsby blog site, over 2 years and now when I updated all the packages, I noticed the markdown options have changed.
Orginally when I used this code, it would show all my blog post accurately with the correct images etc.
export const query = graphql`
{
allMdx(
filter: { fileAbsolutePath: { regex: "/posts/" } }
sort: { order: DESC, fields: frontmatter___date }
limit: 6
) {
nodes {
frontmatter {
alt
title
path
slug
date(formatString: "MMMM Do, YYYY")
image {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
id
}
}
}
`
However, now I tried to choose the options based on what I found from graphql that looks similar to my previous options
Here's the new updated code
export const query = graphql`
{
allMdx(
filter: { body: { regex: "/posts/" } }
sort: { order: DESC, fields: frontmatter___date }
limit: 6
) {
nodes {
frontmatter {
alt
title
path
slug
date(formatString: "MMMM Do, YYYY")
image {
childImageSharp {
gatsbyImageData(layout: FULL_WIDTH)
}
}
}
id
}
}
}
`
However, this code only displays 2 post on my home page and doesn't show any of the images when I need all 6 to display and showcase all the images.
When I run the queries in graphql it only displays the 2 blog post data so I don't know which option to choose to reshow the same things I had before I updated my site with the new versions of gatsby
Here's my gatsby-config file
plugins: [
`gatsby-plugin-image`,
`gatsby-plugin-sharp`,
`gatsby-transformer-sharp`,
{
resolve: "gatsby-plugin-react-svg",
options: {
rule: {
include: /static/,
},
},
},
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `GatsbyJS`,
short_name: `GatsbyJS`,
start_url: `/`,
background_color: `#f7f0eb`,
theme_color: `#a2466c`,
display: `standalone`,
icon: `src/images/fav-1.png`,
icon_options: {
purpose: `any maskable`,
},
},
},
"gatsby-plugin-offline",
`gatsby-plugin-mdx`,
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
`gatsby-plugin-styled-components`,
`gatsby-plugin-react-helmet`,
{
resolve: `gatsby-plugin-sitemap`,
options: {
query: `
{
site {
siteMetadata {
siteUrl
}
}
allSitePage {
nodes {
path
}
}
}`,
resolveSiteUrl: ({ site }) => {
//Alternatively, you may also pass in an environment variable (or any location) at the beginning of your `gatsby-config.js`.
return site.siteMetadata.siteUrl
},
serialize: ({ site, allSitePage }) =>
allSitePage.nodes.map(node => {
return {
url: `${site.siteMetadata.siteUrl}${node.path}`,
changefreq: `weekly`,
priority: 0.7,
}
}),
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `posts`,
path: `${__dirname}/src/posts`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `resources`,
path: `${__dirname}/src/resources`,
},
},
// {
// resolve: "gatsby-plugin-page-creator",
// options: {
// path: `${__dirname}/src/posts`,
// },
// },
{
resolve: `gatsby-plugin-mdx`,
options: {
extensions: [`.md`, `.mdx`],
gatsbyRemarkPlugins: [{ resolve: "gatsby-remark-images" }],
},
},
{
resolve: `gatsby-plugin-google-fonts`,
options: {
fonts: [`nunito\:400s,700`],
display: "swap",
},
},
{
resolve: `gatsby-plugin-mdx`,
options: {
gatsbyRemarkPlugins: [
{
resolve: `gatsby-remark-prismjs`,
options: {
classPrefix: "language-",
inlineCodeMarker: null,
aliases: {},
showLineNumbers: false,
noInlineHighlight: false,
languageExtensions: [
{
language: "superscript",
extend: "javascript",
definition: {
superscript_types: /(SuperType)/,
},
insertBefore: {
function: {
superscript_keywords: /(superif|superelse)/,
},
},
},
],
// Customize the prompt used in shell output
// Values below are default
prompt: {
user: "root",
host: "localhost",
global: false,
},
// By default the HTML entities <>&'" are escaped.
// Add additional HTML escapes by providing a mapping
// of HTML entities and their escape value IE: { '}': '{' }
escapeEntities: {},
},
},
],
},
},
],
UPDATE: For index.js when I use this graph ql query I can finally see my images and the last 6 blog post I set, but not sure what I was supposed to input for the frontmatter so I just left it with empty {}
{
allMdx(
filter: { frontmatter: {} }
sort: { order: DESC, fields: frontmatter___date }
limit: 6
) {
nodes {
id
frontmatter {
title
path
slug
alt
date(formatString: "MMMM Do, YYYY")
image {
childImageSharp {
fluid {
src
}
}
}
}
}
}
}

React-slick with gatsby-plugin-image

I'm trying to use React-slick with gatsby-plugin images and I have the page setup like this.
import React from "react";
import { graphql } from "gatsby"
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import { GatsbyImage } from "gatsby-plugin-image"
const settings = {
autoPlay: true,
arrows: false,
dots: true,
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1,
};
const ImgSlide = ({ data }) => {
return (
<div>
<Slider {...settings}>
<div>
<GatsbyImage fluid={data.image1.childImageSharp.fluid} />
</div>
<div>
<GatsbyImage fluid={data.image2.childImageSharp.fluid} />
</div>
</Slider>
</div>
);
};
export const pageQuery = graphql`
query {
image1: file(relativePath: { eq: "images/icon.png" }) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
image2: file(relativePath: { eq: "images/icon.png" }) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
`
export default ImgSlide;
When i run Gatsby develop I get an error saying image1 is not defined. I really don't know what I'm missing here. I think it has something to do with how I'm trying to define image1 but I'm pretty sure I've used relativePath properly unless I'm not specifying the location properly.
I do have the same image specified twice that is just because I have not imported the photos in just yet I'm just testing to make it work.
gatsby-config setup is
module.exports = {
siteMetadata: {
title: "Inkd Era",
description: "Clothing and brand built for tattoo and tattoed culture",
},
plugins: [
"gatsby-plugin-sass",
"gatsby-plugin-image",
"gatsby-plugin-react-helmet",
"gatsby-plugin-sitemap",
{
resolve: "gatsby-plugin-manifest",
options: {
icon: "src/images/icon.png",
},
},
"gatsby-transformer-remark",
"gatsby-plugin-sharp",
"gatsby-transformer-sharp",
{
resolve: "gatsby-transformer-remark",
options: {
plugins: [
{
resolve: "gatsby-remark-images",
options: {
maxWidth: 650,
},
},
],
},
},
{
resolve: "gatsby-source-filesystem",
options: {
name: "images",
path: `${__dirname}/src/images/`,
},
__key: "images",
},
{
resolve: "gatsby-source-filesystem",
options: {
name: "pages",
path: `${__dirname}/src/pages/`,
},
__key: "pages",
},
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `Inkd Era`,
short_name: `Inkd era`,
start_url: `/`,
background_color: `#000`,
theme_color: `#fafafa`,
display: `standalone`,
icon: `content/assets/gatsby-icon.png`,
},
},
],
};
The structure for the new <GatsbyImage> component when passing the image itself is using the image prop, not fluid. In addition, the query needs to fetch gatsbyImageData, not fluid as you can see in the docs:
import { graphql } from "gatsby"
import { GatsbyImage, getImage } from "gatsby-plugin-image"
function BlogPost({ data }) {
const image = getImage(data.blogPost.avatar)
return (
<section>
<h2>{data.blogPost.title}</h2>
<GatsbyImage image={image} alt={data.blogPost.author} />
<p>{data.blogPost.body}</p>
</section>
)
}
export const pageQuery = graphql`
query {
blogPost(id: { eq: $Id }) {
title
body
author
avatar {
childImageSharp {
gatsbyImageData(
width: 200
placeholder: BLURRED
formats: [AUTO, WEBP, AVIF]
)
}
}
}
}
`
In your scenario, you are mixing the gatsby-image approach, from Gatsby v2 with the new gatsby-plugin-image, which stills in beta, but it's from the v3.
If you want to use the <GatsbyImage>, adapt the query and the component to the needs, otherwise, use the gatsby-image properly like:
import Img from `gatsby-image`
<Img fluid={data.image1.childImageSharp.fluid} />

How to use a SCSS color variable in a Material UI and Gatsby site?

Trying to figure out how to use a color variable from a SCSS file I keep getting an error:
ERROR #98123 WEBPACK
Generating development JavaScript bundle failed
Invalid options object. Sass Loader has been initialized using an
options object that does not match the API schema.
options has an unknown property 'data'. These properties are valid: object { implementation?, sassOptions?, additionalData?, sourceMap?,
webpackImporter? }
File: src/styles/main.scss
I've followed the Gatsby docs and I've installed gatsby-plugin-sass and added it to gatsby-config.js:
{
resolve: `gatsby-plugin-sass`,
options: {
data: `#import "${__dirname}/src/styles/main.scss";`,
},
},
I've added the following to gatsby-browser.js:
// SCSS
import './src/styles/main.scss'
I've tried to bring it in my component:
import React from 'react'
import PropTypes from 'prop-types'
// Material UI
import { AppBar, Toolbar, makeStyles } from '#material-ui/core'
// Components
import Logo from './logo'
import Navigation from './navigation'
const useStyles = makeStyles(() => ({
toolbar: {
background: $FooBar,
display: 'flex',
justifyContent: 'flex-end',
},
navigation: {
display: 'flex',
},
}))
const Header = ({ title, menu }) => {
const { toolbar, navigation } = useStyles()
return (
<>
<AppBar>
<Toolbar className={toolbar}>
<Logo name={title} />
<Navigation className={navigation} menu={menu} />
</Toolbar>
</AppBar>
</>
)
}
Header.propTypes = {
siteTitle: PropTypes.string,
}
Header.defaultProps = {
siteTitle: ``,
}
export default Header
and I tried to import it directly into the component with:
import '../styles/main.scss'
Research
Include sass in gatsby globally:
{
resolve: `gatsby-plugin-sass`,
options: {
data: `#use "${__dirname}/src/styles/main.scss";`,
},
},
import style from '../styles/main.scss'
const useStyles = makeStyles(() => ({
toolbar: {
background: style.FooBar,
display: 'flex',
justifyContent: 'flex-end',
},
navigation: {
display: 'flex',
},
}))
Import sass variables to gatsby component
Gatsby Build Breaks SCSS Export Variables
How to include SCSS Glob in a Gatsby project?
Gatsby fails after using Sass files with '#use 'sass:color'
import style from '../styles/main.scss'
const useStyles = makeStyles(() => ({
toolbar: {
background: style.FooBar,
display: 'flex',
justifyContent: 'flex-end',
},
navigation: {
display: 'flex',
},
}))
{
resolve: `gatsby-plugin-sass`,
options: {
implementation: require('sass'),
},
},
I do not get a build error in the terminal but the background color passed to the component doesn't show up.
In a Gatsby site with Material UI how do I bring in a SCSS color variable to use within a component?
Broken down basic variation of what I've tried to do:
Have you tried changing this:
{
resolve: `gatsby-plugin-sass`,
options: {
data: `#import "${__dirname}/src/styles/main.scss";`,
},
},
To this:
{
resolve: 'gatsby-plugin-sass',
sassOptions: {
data: `#import "${__dirname}/src/styles/main.scss";`,
},
},
It seems that node-sass has some deprecated dependencies, so alternatively to this workaround, you can try upgrading your plugin package to the 3.0.0 version.

Gatsby Graphql Reading image

I want to read a path to an image file from YAML, and use the gatsby-image to create responsive images, but it doesn't let me do what I want.
data.yaml
fileKey: data
profile:
- name: Foo
image: image.jpg
- name: Bar
image: image2.jpg
My query looks like:
query DataQuery {
pagesYaml(fileKey: {eq: "data"}) {
profile {
name
image {
childImageSharp {
fluid(maxWidth: 2048, quality: 100) {
...GatsbyImageSharpFluid
}
}
}
}
}
}
This gives me this error Field "image" must not have a selection since type "String" has no subfields.
However, this below works.
query DataQuery {
pagesYaml(fileKey: {eq: "data"}) {
profile {
name
}
profileImage: file(relativePath: { eq: "image.jpg" }) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
profileImage2: file(relativePath: { eq: "image2.jpg" }) {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
}
The nice thing about the first query is that I can place the profile image inside the profile, so it's easier to manage the data in JavaScript. Is it possible to place the image inside the profile object in the query?
Here's my gatsby-config.js. The images are stored in src/img/.
const proxy = require('http-proxy-middleware');
const yaml = require('./src/yaml');
module.exports = {
siteMetadata: {
title: 'Gatsby + Netlify CMS Starter',
description:
'This repo contains an example business website that is built with Gatsby, and Netlify CMS.It follows the JAMstack architecture by using Git as a single source of truth, and Netlify for continuous deployment, and CDN distribution.',
},
plugins: [
'gatsby-plugin-react-helmet',
{
resolve: 'gatsby-plugin-robots-txt',
options: {
policy: [{ userAgent: '*', disallow: '/' }]
}
},
{
resolve: `gatsby-plugin-sitemap`,
options: {
exclude: [`/admin`]
}
},
'gatsby-plugin-sass',
'gatsby-transformer-yaml',
{
// keep as first gatsby-source-filesystem plugin for gatsby image support
resolve: 'gatsby-source-filesystem',
options: {
path: `${__dirname}/static/img`,
name: 'uploads',
},
},
{
resolve: 'gatsby-source-filesystem',
options: {
path: `${__dirname}/src/pages`,
name: 'pages',
},
},
{
resolve: 'gatsby-source-filesystem',
options: {
path: `${__dirname}/src/img`,
name: 'images',
},
},
{
resolve: 'gatsby-source-filesystem',
options: {
path: `${__dirname}/src/data`,
name: 'data',
},
},
'gatsby-plugin-sharp',
'gatsby-transformer-sharp',
{
resolve: 'gatsby-transformer-remark',
options: {
engines: { yaml },
plugins: [
{
resolve: 'gatsby-remark-relative-images',
options: {
name: 'uploads',
},
},
{
resolve: 'gatsby-remark-images',
options: {
// It's important to specify the maxWidth (in pixels) of
// the content container as this plugin uses this as the
// base for generating different widths of each image.
maxWidth: 2048,
},
},
{
resolve: 'gatsby-remark-copy-linked-files',
options: {
destinationDir: 'static',
},
},
],
},
},
{
resolve: 'gatsby-plugin-web-font-loader',
options: {
custom: {
families: ['Appli Mincho']
}
}
},
{
resolve: 'gatsby-plugin-netlify-cms',
options: {
modulePath: `${__dirname}/src/cms/cms.js`,
},
},
{
resolve: 'gatsby-plugin-purgecss', // purges all unused/unreferenced css rules
options: {
develop: true, // Activates purging in npm run develop
purgeOnly: ['/all.sass'], // applies purging only on the bulma css file
},
}, // must be after other CSS plugins
'gatsby-plugin-netlify', // make sure to keep it last in the array
],
// for avoiding CORS while developing Netlify Functions locally
// read more: https://www.gatsbyjs.org/docs/api-proxy/#advanced-proxying
developMiddleware: app => {
app.use(
'/.netlify/functions/',
proxy({
target: 'http://localhost:9000',
pathRewrite: {
'/.netlify/functions/': '',
},
})
)
},
}
This is likely occurring because Gatsby is inferring your profile.image field as a String instead of a File. This can happen if one or more of the provided path strings does not resolve to a file when you boot Gatsby. Note that Gatsby will not rerun type-inference for existing fields after it boots, so you will need to restart the development server to pick up these changes.

Local image not loading in React [duplicate]

This question already has answers here:
Images not loading in React
(3 answers)
Closed 2 years ago.
Very new to storing local assets on React.
I've configured webpack with file-loader and image-loader and stored the images locally, but for some reason it doesn't seem to be showing:
import React, { Component } from 'react';
import WorkItem from './work-item';
import WorkItemsArray from './work-items-array';
class Work extends Component {
render() {
return (
<div id='work'>
<h1>Work</h1>
<img src={require('../images/weatherImg.png')}/>
<div id='portfolio'>
{WorkItemsArray.map(({ url, img, title, description, github }) => {
return (
<WorkItem
key={title}
url={url}
img={img}
title={title}
description={description}
github={github}
/>
);
})}
</div>
</div>
);
}
}
export default Work;
webpack.config.js
var webpack = require('webpack');
module.exports = {
entry: [
'./src/index.js'
],
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader'
},
{
test: [/\.css$/, /\.scss$/],
exclude: /node_modules/,
loaders: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /.*\.(gif|png|jpe?g|svg)$/i,
use: [
{
loader: 'file-loader',
options: {
name: 'images/[name]_[hash:7].[ext]'
}
}
]
},
{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: false,
},
pngquant: {
quality: '65-90',
speed: 4
},
gifsicle: {
interlaced: false,
},
// the webp option will enable WEBP
webp: {
quality: 75
}
}
}
]
}
]
},
resolve: {
extensions: ['*', '.js', '.jsx']
},
output: {
path: __dirname + '/dist',
publicPath: '/',
filename: 'bundle.js'
},
devServer: {
contentBase: './dist',
historyApiFallback: true
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
})
]
};
FWIW, I'm not getting any errors at all, just that the image doesn't seem to be loading.
Any help greatly appreciated!
Since you assumed you didn't get any error, you have two possibilities: -
Either the image is not visible (maybe because of height and width are small)
Or the whole component <Work /> is not rendered, or even rendered, it is then unmounted without detecting the same.
For the first, force a specific size to the image or replace another image: -
<img src={require('../images/weatherImg.png')} width="400" height="500"/>
For the second, add a componentDidMount and componentWillUnmount and debug, then check the browser console: -
class Work extends Component {
componentDidMount() {
console.log(new Date(), ' Work is mouned 🙃');
}
componentWillUnmount() {
console.log(new Date(), ' Work will be killed 😭');
}
render() {
//...
}
}
let's say you have your images folder inside the public folder.
try:
<img src={require(process.env.PUBLIC_URL + "/images/dog.png")}
for others, if you aren't using webpack try:
<img src={process.env.PUBLIC_URL + "/images/dog.png"}

Resources