Gatsby Graphql Reading image - graphql

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.

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
}
}
}
}
}
}
}

How to create custom resolvers for Gatsby page queries?

I have a Gatsby application pulling data from Sanity.
This is Sanity's schema for the course.js:
import video from './video'
export default {
// Computer name
name: `courses`,
// Visible title
title: `Courses`,
type: `document`,
fields: [
{
name: `title`,
title: `Course title`,
type: `string`,
description: `Name of the course`
},
{
name: `slug`,
title: `slug`,
type: `slug`,
options: {
source: `title`,
maxLength: 100,
}
},
{
name: `price`,
title: `Price`,
type: `number`
},
{
name: `thumbnail`,
title: `Thumbnail`,
type: `image`,
options: {
hotspot: true,
}
},
{
name: `playlist`,
title: `Playlist`,
type: `array`,
of: [
{
title: `Video`,
name: `video`,
type: `video`,
}
]
},
]
}
And this is Sanity's schema for video.js:
export default {
// Computer name
name: `video`,
// Visible title
title: `Video`,
type: `object`,
fields: [
{ name: `title`, type: `string`, title: `Video title` },
{ name: `url`, type: `url`, title: `URL` },
{ name: `public`, title: `public`, type: `boolean`, initialValue: false }
]
}
This Gatsby page query:
{
allSanityCourses {
nodes {
title
price
playlist {
url
title
public
}
}
}
}
Results in:
{
"data": {
"allSanityCourses": {
"nodes": [
{
"title": "Master VS Code",
"price": 149,
"playlist": [
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Introduction",
"public": true
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Philosophy",
"public": false
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Tech and Tools",
"public": false
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Integration",
"public": true
},
{
"url": "https://www.youtube.com/watch?v=PRz1Nv9GUzs",
"title": "Extensions",
"public": false
}
]
}
]
}
},
"extensions": {}
}
To prevent the url field from being injected into the React component this Gatsby page query runs on (because these urls are paid for), I need to remove it, if the public field is set to false.
I've tried inserting this into gastby-node.js:
exports.createSchemaCustomization = ({ actions, schema }) => {
const { createTypes } = actions
const typeDefs = [
schema.buildObjectType({
name: "SanityCourses",
fields: {
playlist: {
type: "[SanityVideo]",
url: {
type: "String",
resolve: (source) => "nope"
},
},
},
interfaces: ["Node"],
}),
]
createTypes(typeDefs)
}
And:
exports.createResolvers = ({ createResolvers }) => {
const resolvers = {
SanityCourses: {
playlist: {
type: "[SanityVideo]",
url: {
type: "String",
resolve(source, args, context, info) {
return "nope"
},
}
},
},
}
createResolvers(resolvers)
}
But neither seems to work. The url field returns the url as always. The resolvers don't even seem to fire (I've tried putting console.log()'s in them).
Any help on how to remove the url field if the public field is set to false, or general direction to go in would be very appreciated.
Ditch the attempt in createSchemaCustomization since you don't need to customize the schema here (though I believe there is a way to achieve what you want using it, it is not expected that the data in it is sourced from existing nodes, and this undeclared dependency can create caching issues).
Then update your createResolvers function to something like this:
exports.createResolvers = ({ createResolvers }) => {
createResolvers({
SanityVideo: {
safeUrl: {
type: "String",
resolve: (source, args, context, info) => source.public ? source.url : null
},
},
})
}
I don't believe resolvers can replace schema-originated nodes (fields), hence using safeUrl instead of url
The type you are adding a field to is SanityVideo, and it doesn't matter what the parent node is—this will apply to all instances of SanityVideo in your data

Not getting a drop down menu for "img" in Gatsby / GraphQL

I am following this tutorial.
I have trips.json in my data folder
[
{
"img": "../assests/images/bahamas.jpg",
"name": "Bahama Beach"
},
{
"img": "../assests/images/china.jpg",
"name": "Chinese Palace"
},
{
"img": "../assests/images/dubai.jpg",
"name": "dubai"
},
{
"img": "../assests/images/monke.jpg",
"name": "monke",
"alt": "monke monke monke monke"
}
]
Here is my gatsby-config.js
module.exports = {
siteMetadata: {
title: `My Gatsby Project`,
description: `Made with Gatsby.`,
author: `#gatsbyjs`,
siteUrl: `https://gatsbystarterdefaultsource.gatsbyjs.io/`,
},
plugins: [
`gatsby-transformer-json`,
{
resolve: `gatsby-source-filesystem`,
options: {
path: `./src/data`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/assets/images`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `videos`,
path: `${__dirname}/src/assets/videos`,
},
},
{
resolve: `gatsby-plugin-styled-components`,
options: {
// Add any options here
author: `me`,
},
},
`gatsby-plugin-react-helmet`,
`gatsby-plugin-image`,
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `gatsby-starter-default`,
short_name: `starter`,
start_url: `/`,
background_color: `#663399`,
theme_color: `#663399`,
display: `minimal-ui`,
icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
},
},
`gatsby-plugin-gatsby-cloud`,
// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.dev/offline
// `gatsby-plugin-offline`,
],
}
At localhost:8000/__graphql, I am getting a checkbox for "img."
However, the tutorial makes extensive use of many properties within the "img" attribute.
I have tried to stop the process, do gatsby clean and restart the process.
So I want to figure out why I am not seeing this and how I can get this drop-down to appear on my screen.
Solved it by adding the following to gatsby-node.js
exports.createResolvers = ({
actions,
cache,
createNodeId,
createResolvers,
store,
reporter,
}) => {
const { createNode } = actions
createResolvers({
StrapiPageContentArticleGallery: {
imageFile: {
type: `File`,
resolve(source, args, context, info) {
return createRemoteFileNode({
url: `${source.url}`, // for S3 upload. For local: `http://localhost:1337${source.url}`,
store,
cache,
createNode,
createNodeId,
reporter,
})
},
},
},
})
}

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 query gatsby image using graphiql

i have image in /src/assests/images/basketball which I want to query using graphiql.
I tried pasting this in my graphiql
query {
placeholderImage: file(relativePath: { eq: "basketball.jpeg" }) {
childImageSharp {
fluid(maxWidth: 300) {
...GatsbyImageSharpFluid
}
}
}
}
but it keeps on saying ...GatsbyImageSharpFluid unknown fragment. I have a vague idea about graphQL but can someone help me out on how i can query queries using graphiQl in gatsby?
This is my gatsby.config.js
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/assests/images`,
},
},
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `gatsby-starter-default`,
short_name: `starter`,
start_url: `/`,
background_color: `#663399`,
theme_color: `#663399`,
display: `minimal-ui`,
// icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
},
},
And my folder structure of where the files are
Gatsby image fragments limitation
Note, due to a limitation of GraphiQL, you can not currently use these fragments in the GraphiQL IDE.
In GraphiQL change your query to:
query {
placeholderImage: file(relativePath: { eq: "basketball.jpeg" }) {
childImageSharp {
fluid(maxWidth: 300) {
base64
aspectRatio
src
srcSet
sizes
}
}
}
}

Resources