Webiny Page Bulder and Gatsby

Hi all.

TL;DR: Has anyone managed to get Pages from the Page Builder app rendered at build time in Gatsby?

I am trying to build a site using Gatsby and Webiny and it is working great for the most part. I can get the gatsy-image component to pull images from the gatsby-source-graphql plugin. I can get my components and pages to pull content from the models in the Headless CMS app. All my Gatsby pages and components are generated statically at build time and Webiny is never queried at runtime. This is great and it is just what I am trying to achieve.

Now, I would like to add pages from the Page Builder app to the mix. I am doing some tests but I am having trouble making it work. I followed the steps in the example at https://github.com/webiny/webiny-examples/tree/master/cra-page-builder, which looks like this:

However, since Gatsby has it’s own machinery for querying the data sources used to populate pages, I had to make some changes to this. I created a query for Gatsby to get the Page content directly, and then I changed the <Page/> component to use the data prop instead of the url prop. This works in so far as that the Page component is passed in correct content from the CMS.

However, rendering fails because of what looks like a confusion between the image-component in the these two modules:

  • @webiny/plugins/
  • @webiny/app/node_modules/@webiny/plugins/

Additionally, the Page component used by this code sends its own queries for the header (and maybe other components) which I do not want to happen at runtime.

Is there a way to get the <Page/> component use only the content I give it? Or is there another way to generate the required HTML from the CMS content that comes from the Page Builder app?

Thanks!
Paul.

@Paul_Dermody I’ll try to provide some information that may get you going.

1) Webiny is always setup as a monorepo. Monorepos hoist npm packages to the top-level node_modules, resolving duplicate package problems. The problem you’re experiencing is very common in non-monorepo environment. You can try solving it by adding a resolution to your Gatsby webpack config, which will always point to the exact @webiny/plugins path:

{
    // ... usual webpack stuff
    resolve: {
        alias: {
            "@webiny/plugins": require.resolve("@webiny/plugins")
        }
    }
}

This should help with plugins resolution. It’s important because that package contains an instance of PluginsContainer which is shared across the code so it’s similar to React Context - you always want to resolve to the same file path.

2) The extra queries during Page render: the usual flow is - load the page, get the layout from page data, find the layout plugin, and then render the page within the layout component.

What you need, is an empty layout, which will respect the rendering flow, but not render anything besides the page content.

To achieve it, you’ll need to register a new layout plugin and use it in both Webiny admin app, and in your Gatsby setup:

export default {
  name: "pb-page-layout-empty",
  type: "pb-page-layout",
  layout: {
    name: "empty",
    title: "Empty layout",
    component: ({ children }) => {
      return children;
    }
  }
};

Now use this layout to create your pages, and you will only get the actual page content, without the headers, footers, or anything else.

Hope this helps! If you need more help, join our Community Slack, it will be faster and easier to communicate there, and there are already 400+ members who can also help if we’re busy.

Btw. for v5, we’ll be “ejecting” a lot of this stuff so it will be within your Webiny project and you’ll be able to customize everything regarding page rendering. It will also give you more ideas on how to integrate it with Gatsby.

Cheers! :beers:

1 Like

Thanks Pavel. Let me chew on this a bit and finish up some other stuff I am doing and I will take another crack at it. I will report back here when done. I think it is an important feature to be able to take advantage of. Especially since right now the Rich Text editor does not allow images yet.

Thanks,
Paul.

In v5 the RichTextEditor is a lot better. We replaced Slate.js with editor.js and we now also support images :slight_smile: Stay tuned for the beta release by the end of this year :rocket:

1 Like

I tried out your suggestions and they worked like a charm Pavel!

This makes Webiny many times more valuable as a CMS option for Gatsby. Clients can use the Page Builder to create much more compelling pages than is possible with Rich Text (even after images are added in V5) or Markdown and less need for rigid templates. (I look forward to trying out the new V5 feature which lets us add CMS model data into the pages too.)

1 Like

Glad it worked!

Regarding v5, we’ve already prepared our page builder for multi-editor functionality. What it means is that you as a developer will be able to create different editor plugins. Out of the box you get our visual page builder, but you can also add Markdown, or plain WYSIWYG editor of your choice, and edit the content using the most suitable editor. So it’s several editors within one system :wink: Imagine creating a page and going Nah, I want to write this as Markdown - click Markdown, then your content editor needs to build a landing page - he’ll go for Visual editor, etc.

How cool is that? :wink:

1 Like

I spoke too soon @pavel. It worked in development. But when I did a production build it failed due to the dependency on react-router-dom which Gatsby cannot use.

I played around with it and I can get it working if I replace some of the page rendering plugins (Button and Image for a start) and have them use the Gatsby Link component instead of the one from the Webiny router. To be honest, I have just started learning how both Gatsby and Webiny work so there might be an easier way to solve this problem.

Could one approach be to change the Link component used in the Webiny page rendering code to use a plug-in instead? It certainly would help potential Gatsby developers.

Paul.

@Paul_Dermody our own Link component is there for a reason; it processes some plugins to allow page preloading and optimize how the site behaves when used in full Webiny setup.

Having Page Builder working with Gatsby was not our original intention so we would need to debug it on our side to see all the problems that are present in such a setup.

Gatsby uses its own Link component to “scan” the whole app at build time and generate static files with correct preload links, etc. I’m afraid that the only fix is to implement your own rendering plugins for all the elements used in the page builder (at least the ones you use). To see the default implementation see this https://github.com/webiny/webiny-js/tree/master/packages/app-page-builder/src/render/plugins/elements