Make graphql query outside a JSX component in Gatsby - reactjs

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.

Related

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

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.

Gatsby.js (React) - graphql query in gatsby-browser.js

I have a plugin TypeWriting in Gatsby.js (React). It looks like this:
/* file: gatsby-browser.js */
const typeWriting = () => {
new Typewriter('#intro-typing', {
strings: ['Drupal', 'WordPress', 'OpenCart'],
});
}
export const onInitialClientRender = () => {
typeWriting();
}
I want to set for "string" - own array from graphql query
How I can work with graphql query in gatsby-browser.js?
gatsby-browser.js is a file that lets you respond to actions within the browser, and wrap your site in additional components. The Gatsby Browser API gives you many options for interacting with the client-side of Gatsby. So I don't think that you can trigger, outside any API or method, any kind of GraphQL query.
If you want that strings array to be "automated" you can use environment variables and get place it as values of the array.

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

How to progamatically create pages in gatsby with a CMS backend?

I have a Django CMS that serves as my back-end application. And I'm trying to create pages dynamically in my Gatsby front-end site. My Django application is exposed over GraphQL using Graphene. But I'm not able to query the slugs from backend CMS and create pages using gatsby-node.js. How do I create pages when I create a page in the back-end application?
The idea being
//gatsby-node.js
exports.createPages = ({ graphql, actions }) => {
const pages = graphql`
{
blogPages{
edges{
node{
slug // this slug supposed to come from the backend CMS (Atleast i think)
}
}
}
}
`;
const { createPage } = actions
const blogTemplate = path.resolve(`src/templates/blogTemplate.js`);
pages.blogPages.edges.forEach(edge => { //this should help to create dynamic pages - slug coming from backend CMS
const slug = edge.node.blogpage.slug;
createPage({
path: slug,
component: blogTemplate
})
})
}
It's been said in the comments already, but just to summarize: since Gatsby is a static site generator you cannot dynamically add pages at runtime. Each page corresponds to its own html file that needs to be created on your webserver. That is not something you can do at runtime.
What you can do is to set up a continuous integration workflow where you have a build running in the cloud somewhere. Trigger it when you make a change in Django, or alternatively run it regularly (hourly/daily) to update the site.
If running a rebuild does not work for your use case you need to look at an entirely different architecture.

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