I couldn't find this issue anywhere else, so it might be that it's an implementation problem, but as I'm using v2 beta, I figured there's a good chance that this is a bug.
I fetch data from an API on gatsby-node.js and create nodes for each object but they are only made available on graphQL at specific points, not allowing me to create pages from them.
It seems a bit random, so I've shot them on video and put it on YouTube:
As nodes are registered on "onCreatedNode", I'd expect to be able to access them on graphQL every time and be able to create pages from them.
I can only query the created nodes' types at times, and never when I have the createdPages function working.
System:
OS: Windows 10
CPU: x64 Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz
Binaries:
Yarn: 1.4.0 - C:\Users\henri\AppData\Roaming\npm\yarn.CMD
npm: 6.0.1 - C:\Program Files\nodejs\npm.CMD
Browsers:
Edge: 42.17134.1.0
npmPackages:
gatsby: next => 2.0.0-beta.9
gatsby-plugin-react-helmet: next => 3.0.0-beta.2
gatsby-plugin-sass: next => 2.0.0-beta.2
gatsby-plugin-styled-components: ^2.0.11 => 2.0.11
gatsby-plugin-typescript: ^1.4.20 => 1.4.20
gatsby-source-filesystem: ^1.5.39 => 1.5.39
module.exports = {
siteMetadata: {
title: 'Gororobas',
description: 'Descubra uma receita vegetariana/vegana com o que voc锚 t锚m em casa!',
siteUrl: 'https://gororobas.netlify.com',
},
plugins: [
'gatsby-plugin-react-helmet',
'gatsby-plugin-typescript',
{
resolve: 'gatsby-plugin-sass',
options: {
file: 'src/styles/main'
}
},
],
}
{
"name": "gororobas",
"description": "Gororobas",
"version": "0.5.0",
"author": "Henrique Cavalieri <[email protected]>",
"dependencies": {
"@sanity/block-content-to-react": "^1.3.9",
"@sanity/client": "^0.132.2",
"@sanity/image-url": "^0.132.2",
"@types/react": "^16.4.1",
"@types/react-dom": "^16.0.6",
"@types/react-helmet": "^5.0.6",
"@types/react-router": "^4.0.27",
"babel-plugin-styled-components": "^1.5.1",
"babel-plugin-transform-typescript": "^7.0.0-alpha.19",
"gatsby": "next",
"gatsby-plugin-react-helmet": "next",
"gatsby-plugin-sass": "next",
"gatsby-plugin-styled-components": "^2.0.11",
"gatsby-plugin-typescript": "^1.4.20",
"gatsby-source-filesystem": "^1.5.39",
"node-sass": "^4.9.0",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"react-helmet": "^5.2.0",
"slugify": "^1.3.0",
"styled-components": "^3.3.3"
},
"keywords": [
"gatsby"
],
"license": "MIT",
"scripts": {
"build": "gatsby build",
"develop": "gatsby develop",
"format": "prettier --write 'src/**/*.js'",
"test": "echo \"Error: no test specified\" && exit 1"
},
"devDependencies": {
"prettier": "^1.12.0"
},
"repository": {
"type": "git",
"url": "https://github.com/gatsbyjs/gatsby-starter-default"
}
}
const crypto = require('crypto');
const path = require('path');
const slugify = require('slugify');
const sanityClient = require('@sanity/client');
const queries = require('./sanityQueries');
const Sanity = sanityClient({
projectId: 'projectId', // not the real id
dataset: 'production',
useCdn: true,
});
exports.onPreBootstrap = async ({
actions
}) => {
const {
createNode
} = actions;
const data = await Sanity.fetch(queries);
console.log(data);
data.recipes.forEach(recipe => {
const {
body,
instructions,
ingredients,
meta: {
title
},
info: {
cookingTime,
prepareTime,
servings
}
} = recipe;
// creates nodes on graphQL
// reference: https://www.gatsbyjs.org/docs/bound-action-creators/#createNode
createNode({
title,
body,
instructions,
ingredients,
cookingTime,
prepareTime,
servings,
created: recipe._createdAt,
updated: recipe._updatedAt,
slug: recipe.slug || slugify(title),
// mandatory fields
id: recipe._id,
parent: null,
children: [],
internal: {
type: 'Recipe',
// Content digest is used for caching the node
contentDigest: crypto
.createHash(`md5`)
.update(JSON.stringify(recipe))
.digest(`hex`),
description: title,
}
})
});
data.ingredients.forEach(ingredient => {
const {
name,
price,
description,
icon
} = ingredient;
createNode({
name,
price,
description,
icon,
// mandatory fields
id: ingredient._id,
parent: null,
children: [],
internal: {
type: 'Ingredient',
contentDigest: crypto
.createHash(`md5`)
.update(JSON.stringify(ingredient))
.digest(`hex`),
description: name,
}
})
});
}
exports.onCreateNode = ({ node }) => {
if (node.internal.type === 'Recipe' || node.internal.type === 'Ingredient') {
console.log('\n working \n', (node.name || node.title))
}
}
exports.createPages = async ({ actions, graphql }) => {
const data = await graphql(`
{
allSitePage {
edges {
node {
id
}
}
}
}
`);
console.log(data);
}
gatsby-browser.js: N/A
gatsby-ssr.js: N/A
Try changing exports.onPreBootstrap to exports.sourceNodes (which is where You should be creating nodes) - right now in v2 onPreBootstrap is run before cache is invalidated - so this may cause your nodes to simply be deleted
You're absolutely right, @pieh !! Thank you for the quick and precise answer <3
Just as a final question, when sourcing from an external API the best practice is to create a source plugin yourself?
PS: Feel free to close the issue! :D
Just as a final question, when sourcing from an external API the best practice is to create a source plugin yourself?
Yeah! You can either use an existing source plugin or create your own source plugin. You can create a local plugin if it's a one-off plugin just for your site.
There's some docs and a tutorial on creating source plugins if you want to give it a go.
If you see anything in the docs that could be improved, pull requests are always welcome.