Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Sample gatsby-config.js enabling live preview in Craft CMS
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();
});
},
};
@provedev

This comment has been minimized.

Copy link

@provedev provedev commented Mar 6, 2020

Getting the following error: UNHANDLED REJECTION Schema must contain uniquely named types but contains multiple types named "Craft".

Any ideas?

@anthonyferreol

This comment has been minimized.

Copy link

@anthonyferreol anthonyferreol commented Mar 6, 2020

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?

@monachilada

This comment has been minimized.

Copy link
Owner Author

@monachilada monachilada commented Mar 7, 2020

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.

@anthonyferreol

This comment has been minimized.

Copy link

@anthonyferreol anthonyferreol commented Mar 8, 2020

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 });
});
@provedev

This comment has been minimized.

Copy link

@provedev provedev commented Mar 9, 2020

Thanks. How exactly do I implement this?

@Digital-E

This comment has been minimized.

Copy link

@Digital-E Digital-E commented Apr 18, 2020

Thanks for your solution @anthonyferreol, it's working for me!

@wfendler

This comment has been minimized.

Copy link

@wfendler wfendler commented Jun 24, 2020

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();
      }
    });
  },
};
@jamie-l-robertson

This comment has been minimized.

Copy link

@jamie-l-robertson jamie-l-robertson commented Oct 3, 2020

@wfendler Did you manage to figure out your latest draft issue, I have hit the same problem...

@wfendler

This comment has been minimized.

Copy link

@wfendler wfendler commented Oct 7, 2020

@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

@jamie-l-robertson

This comment has been minimized.

Copy link

@jamie-l-robertson jamie-l-robertson commented Oct 7, 2020

@wfendler Ah excellent, thanks for the heads up!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.