-
-
Save monachilada/af7e92a86e0d27ba47a8597ac4e4b105 to your computer and use it in GitHub Desktop.
const { createHttpLink } = require('apollo-link-http'); | |
const fetch = require('node-fetch'); | |
const store = require('store'); | |
const sourceNodes = require('gatsby/dist/utils/source-nodes'); | |
require('dotenv').config(); | |
const craftGqlUrl = process.env.CRAFT_GQL_URL; | |
const craftGqlToken = process.env.CRAFT_GQL_TOKEN; | |
module.exports = { | |
plugins: [ | |
{ | |
resolve: 'gatsby-source-graphql', | |
options: { | |
typeName: 'Craft', | |
fieldName: 'craft', | |
createLink: () => | |
createHttpLink({ | |
uri: `${craftGqlUrl}`, | |
headers: { | |
Authorization: `Bearer ${craftGqlToken}`, | |
}, | |
fetch: (uri, options) => { | |
const token = store.get('X-Craft-Token'); | |
return fetch( | |
`${uri}${token !== undefined ? `?token=${token}` : ''}`, | |
options, | |
); | |
}, | |
}), | |
}, | |
}, | |
], | |
developMiddleware: app => { | |
app.use('*', (req, res, next) => { | |
if (req.query.token) { | |
store.set('X-Craft-Token', req.query.token); | |
sourceNodes(); | |
} | |
next(); | |
}); | |
}, | |
}; |
Have the same problem here. I think sourceNodes is only called during the bootstrap sequence but cannot be used to "update" the GRAPHQL schema. Any ideas?
Unfortunately one of the Gatsby updates released since I first posted this changed something in the sourceNodes sequence with the consequence being this code is no longer working. Unfortunately I haven’t had the time to dig into exactly why. I would be grateful for any tips and would happily update the snippet.
However, long term I’ve begun to move away from this solution as it was never going to scale well on larger sites, since EVERY query needs to be rerun. I’ve resigned myself to waiting for the official Gatsby plugin which is in the works.
This do it: (based on the refresh function from the POST api (__refresh): with webHook if needed (can be removed)
createSchemaCustomization({ refresh: true }).then(() => {
sourceNodes({ webhookBody });
});
Thanks. How exactly do I implement this?
Thanks for your solution @anthonyferreol, it's working for me!
So, I kind of got this working. I definitely need a deeper understanding of middleware and how createLink
and createHttpLink
work to finish this up but perhaps someone else on here could help me out.
By adding createSchemaCustomization
and fixing the sourceNodes
reference I was able to get this close. The problem here is that when Craft loads this in the iframe it doesn't load the latest draft. If refetchInterval
is set however, it will load the correct content whenever that interval fetches new data. So, for now I just have the interval set to 30 seconds so content editors don't see changes immediately but they rarely have to wait long to see updates.
Does anyone else see what's wrong in here? We're hosting this on Heroku, running gatsby develop -p $PORT -H 0.0.0.0
(based on this article by @andreaskeller)
const { createHttpLink } = require("apollo-link-http");
const fetch = require("node-fetch");
const store = require("store");
const sourceNodes = require("gatsby/dist/utils/source-nodes").default;
const createSchemaCustomization = require("gatsby/dist/utils/create-schema-customization")
.createSchemaCustomization;
require("dotenv").config();
const craftGqlUrl = process.env.CRAFT_GQL_URL;
const craftGqlToken = process.env.CRAFT_GQL_TOKEN;
module.exports = {
plugins: [
{
resolve: "gatsby-source-graphql",
options: {
typeName: "Craft",
fieldName: "craft",
refetchInterval: 30,
createLink: () =>
createHttpLink({
uri: `${craftGqlUrl}`,
headers: {
Authorization: `Bearer ${craftGqlToken}`,
},
fetch: (uri, options) => {
const token = store.get("X-Craft-Token");
return fetch(
`${uri}${token !== undefined ? `?token=${token}` : ""}`,
options
);
},
}),
},
},
],
developMiddleware: (app) => {
app.use("*", (req, res, next) => {
if (req.query.token) {
// Reject app-data.json requests, they don't contain a token and override
// the page request that sets the token
if (!req.baseUrl.includes("app-data.json")) {
store.set("X-Craft-Token", req.query.token);
createSchemaCustomization({ refresh: true }).then(() => {
// This function only works if I pass {} or { webhookBody: null }
sourceNodes({});
});
}
// next() to moves on to the next middleware in the stack
// http://expressjs.com/en/api.html#app.use
next();
}
});
},
};
@wfendler Did you manage to figure out your latest draft issue, I have hit the same problem...
@jamie-l-robertson I haven't. After making several attempts I've given up until we have better Gatsby + Craft support through a new source plugin. It seems like this is coming soon: https://github.com/craftcms/craft-gatsby
Discord conversation starts around here: https://discordapp.com/channels/456442477667418113/629094175509446657/752907415003070514
@wfendler Ah excellent, thanks for the heads up!
Getting the following error: UNHANDLED REJECTION Schema must contain uniquely named types but contains multiple types named "Craft".
Any ideas?