How do I use GraphQL to query an image from Contentful? - reactjs

I am building a basic site with Gatsby and have connected it to Contentful. I uploaded 2 assets to Contentful:
First asset looks like:
The second asset is 100% identical other than the title which is test-two.
If I use the about query and pass in the URL into an img tag, my image will display. However, I am trying to use GatsbyImage and can't seem to figure out the problem.
I've been trying to follow this tutorial and using but I am unable to get anything to render. How does my query need to change in order to use gatsby-image?

In this case, you are querying for the url, filename and contentType. To be able to use GatsbyImage you need to query the node created from Gatsby (which is gatsbyImageData) it should be contained in the name of the Contentful asset node. Something like:
{
allContentfulAsset {
edges {
node {
test {
title
gatsbyImageData(layout: CONSTRAINED)
}
}
}
}
}
Check for the created nodes in the GraphiQL playground (localhost:8000/___graphql).
Once done, in your component, you should be able to do something like:
import { graphql } from "gatsby"
import { GatsbyImage, getImage } from "gatsby-plugin-image"
function SomePage({ data }) {
const image = getImage(data.allContentfulAsset.test)
return (
<section>
<GatsbyImage image={image} alt={`Some alt text`} />
</section>
)
}
export const pageQuery = graphql`
query {
allContentfulAsset {
edges {
node {
test {
title
gatsbyImageData(layout: CONSTRAINED)
}
}
}
}
}
`
If the node doesn't appear, check your configurations in the gatsby-config.js file.
⚠️ Disclaimer
Watch out, the tutorial you are trying to use is using gatsby-image (from Gatsby v2 backward), where the rendered component is Img, imported from gatsby-image while you are using GatsbyImage (from Gatsby v3 onwards), imported from gatsby-plugin-image. The first one is deprecated and the query structure is slightly different. As you can see at the top of the guide you shared:
The gatsby-image package is now deprecated. The new Gatsby image
plugin has better performance, cool new features and a simpler
API. See the migration guide to learn how to upgrade.

Related

featuredImage does not appear in GraqhiQL , Gatsby

i am trying to develop a blog site for myself.and i decided to make it with gatsby and contentful. and i followed this tutorial
query code
query MyQuery {
allContentfulBlogPost {
edges {
node {
author {
name
}
createdAt
body {
body
}
title
featuredImage {
file {
url
}
}
}
}
}
}
output :
"message": "Cannot query field \"featuredImage\" on type \"ContentfulBlogPost\".",
why featuredImage does not appear in allContentfulBlogPost ? and how can i find it ?
my gatsby-config.js file:
plugins: [
`gatsby-plugin-react-helmet`,
`gatsby-image`,
`gatsby-transformer-remark`,
{
resolve: `gatsby-remark-images`,
options: {
maxWidth: 740,
wrapperStyle: `margin-bottom: 2.2rem;`,
},
},
i already added gatsby-image and gatsby-remark-images but it didnt help.
if you have any idea about this topic please respond.
any response would be appreciated
Gatsby provides GraphQL to fetch data without remark.
import { graphql } from "gatsby"
export const pageQuery = graphql`
query BlogPostBySlug($slug: String!) {
contentfulBlog(slug: { eq: $slug }) {
blogTitle
blogImage {
fluid (maxWidth: 500) {
...GatsbyContentfulFluid_withWebp
}
title
resize {
src
width
height
}
}
}
}
`
As you can see the query, you can fetch images using fluid or fixed.
I fetched image using fluid and webp since webp image type is a perfect choice for Lighthouse score.
And use Img tag(not img) to display image.
<Img fluid={post.blogImage.fluid} alt={post.blogImage.title} />
https://www.gatsbyjs.org/packages/gatsby-image/
The issue comes from Contentful side, it breaks before reaching your Gatsby app (when gathering data) that's why your gatsby-remark-images doesn't fix it.
When dealing with images in Contentful you must upload a dummy image for your new schema (featuredImage). Just an image to be retrieved with GraphQL query. Afterwards you can replace this image for your definitive content.
This is because internally, GraphQL schema is not able to infer the type of an image (it may happen with other fields too of other types) if you don't upload it at least once for your allContentfulBlogPost content model. It's a known bug that must be bypassed by this way until they fix it.

WPGraphQl Yoast SEO Plugin for GatsbyJS build

I am trying to create a SEO component for all of my posts in my GatsbyJS build. The site is built with gatsby-source-graphql as well as WPGraphQL WordPress plugin on my WP installation. For my SEO component am I trying to use WPGraphQl Yoast SEO Plugin.
I am querying meta description etc. in a fragment and then passing this information in a React helmet using an SEO component.
This kinda works and is querying the metadescription when I console.log. My problem is now that it will only return metaDesc for the first post and is, therefore, passing the same metaDesc to all of my posts.
If I pass in a filter it will display the correct metadescription:
query MyQuery {
wpgraphql {
posts(where: {id: 608}) {
edges {
node {
seo {
metaDesc
title
}
}
}
}
}
}
During createPosts I figured I needed to add some kind of dynamic filter that would only query for specific ID so I tried the following:
query MyQuery {
wpgraphql {
posts(where: {id: ${id}}) {
edges {
node {
seo {
metaDesc
title
}
}
}
}
}
}
However, this solution is giving me an error: String interpolations are not allowed in graphql fragments.. I am therefore looking for a solution on how I could pass in the right metaDescription for each individual posts instead of the current situation where it will only pass metaDesc of the first post.
You can find my repo here

Make graphql query outside a JSX component in Gatsby

I have a .ts(not .tsx) file which just exports a json object like
const obj = {
img1: gql_img1,
img2: gql_img2
}
I want gq1_img1 and gq1_img2 to be the results of a graphql query
I found a solution which uses Apollo Client, but it doesn't look like they're using Gatsby and I don't think Gatsby uses a client.
The problem with using useStaticQuery is that it's a hook, if I try to use it like in the snippet below, I get "Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:"
const gql = () => {
const gql = useStaticQuery(graphql
`query adQuery {
invoiceNinja300x250: file(
extension: {regex: "/(jpg)|(jpeg)|(png)/"},
name: {eq: "IN-300x250-2"}
){
childImageSharp {
fluid(maxWidth: 250) {
...GatsbyImageSharpFluid_withWebp_noBase64
}
}
},
invoiceNinja600x300: file(
extension: {regex: "/(jpg)|(jpeg)|(png)/"},
name: {eq: "IN-600x300-2"}
){
childImageSharp {
fluid(maxWidth: 250) {
...GatsbyImageSharpFluid_withWebp_noBase64
}
}
}
}`
)
return gql
}
const GQL = gql()
Like I mentioned in your reddit post, if you're not using a page query or static query, you'll need Apollo Client or some other gql client.
I found a solution which uses Apollo Client, but it doesn't look like they're using Gatsby and I don't think Gatsby uses a client.
Gatsby and GraphQL clients are different things. Gatsby is a React framework for building static websites and uses graphQL to fetch data in various ways.
A GraphQL client is much like fetch or axios, they are libraries used to request, post, update, delete data from a REST API.
Can you explain your use case a bit? Maybe there is a more Gatsby way of doing it.
Have you considered the React Context API? On the production Gatsby app I work on that's what we use for global variables like some JSON/object data. It allows you in some sort of high level/layout/data layer component to stuff some values you get from a different file into your app to use with other components.

Gatsby site's images aren't showing on mobile devices

I'm building portfolio site with Gatsby+Wordpress combination. If I run this setup locally or at Github pages everything seems to look normal when using desktop/laptop. If I visit site which is published to Github pages and view with mobile device images aren't showing at all.
I found this solution and added it to my gatsby-node.js like this:
const _ = require(`lodash`)
const Promise = require(`bluebird`)
const path = require(`path`)
const slash = require(`slash`)
// This is the solution I found but it's not working in my case
// ----------
if (process.env.NODE_ENV === "development") {
process.env.GATSBY_WEBPACK_PUBLICPATH = "/"
}
// ----------
exports.createPages = ({ graphql, actions }) => {
...
I didn't found any other solutions and it seems that I can't solve it by myself.
Link to site
Link to repo
Hopefully I provided enough information so you can catch the idea, if not ask and I tell more. Thanks in advance!
I got this working by changing the way I query images. At first I used for example this:
query {
wordpressWpPortfolio {
acf {
portfolio_gallery {
source_url
}...
This produced wrong kind of URLs for images. Images pointed to my localhost instead of folder inside my repo.
I changed query method to this:
query {
wordpressWpPortfolio {
acf {
portfolio_gallery {
localFile {
childImageSharp {
fluid(maxWidth: 500, quality: 100) {
src
srcSet
aspectRatio
sizes
base64
}...
This query for gatsby-image had to be done manually because gatsby-config.js doesn't support fragments like:
fixed(width: 300, height: 300) {
...GatsbyImageSharpFixed
}
This line in your gatsby config looks to be the issue: baseUrl: "localhost:8888/robertsalmi.fi",
I suspect the wordpress plugin uses that to prefix all the images, as your live site is showing them all with that base url. You'll need to provide the correct base, so it can build the image links properly.

Gatsby + Markdown: How to get data from a specific markdown file into a single page?

I'm new to Gatsby, and making my best to learn it (along with React, in which I have no prior knowledge either). I'd like to create a single page getting data from one or several markdown files.
For now I'm testing it out with just Gatsby, in order to later reproduce that technique with Netlify CMS markdown files (and be able to update the page texts with Netlify CMS admin panel).
So far, I've managed to add markdown pages to Gatsby, thanks to this tutorial. But this method only creates dynamic pages, which is far more complex than what I need.
Is there a simple way to import one specific markdown file, let's say src/markdowns/hero-texts.md, in (let's also say) pages/index.js, and then call data with their frontmatter tags, in the cleanest way as possible?
I've tried countless researches on Google just to find which plugin or coding term would handle that, without success. I totally get some of the explanations above may be full of technical misunderstandings, sorry for that...
You have a markdown file called hero-texts.md and you want to be able to query its frontmatter content.
Install the plugins gatsby-transformer-remark and gatsby-source-filesystem and setup the gatsby-source-filesystem options to find your markdown files.
// gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
name: `markdown`,
path: `${__dirname}/src/markdowns/`
}
},
`gatsby-transformer-remark`
]
}
You could make a graphql page query like this inside index.js (then the result of the query is automatically added to your index component under props.data)
// src/pages/index.js
import React from "react"
import { graphql } from "gatsby"
const IndexPage = ({data}) => {
return (
<>
<p>{data.markdownRemark.frontmatter.author}</p>
<p>{data.markdownRemark.frontmatter.date}</p>
<p>{data.markdownRemark.frontmatter.title}</p>
</>
)}
export default IndexPage
export const pageQuery = graphql`
query IndexPageQuery {
markdownRemark(fileAbsolutePath: { regex: "/hero-texts.md/" }) {
frontmatter {
author
date
title
}
}
}
`
It will perform the graphql query at build time, and add the result of the query to the data prop of the IndexPage page component.
So in effect, pulling in all the frontmatter fields from a markdown file that looked like this.
// src/markdowns/hero-texts.md
---
title: "Gatsby + Markdown: How to simply get data from a specific markdown in a single page?"
author: Florent Despinoy
date: 2019-08-06
---
# This is my markdown post
The content of this markdown file would not be queried by pageQuery (only the frontmatter would)

Resources