What you'll learn
  • how to create a custom page Builder element
  • how to register plugins in Webiny applications

Introduction
anchor

Out of the box, Webiny’s Page Builder app provides a plethora of ready-made page elements we can use to create both simple and complex pages for our website. Furthermore, on top of the default set, users can also create their custom page elements, which is what this article demonstrates.

In this short article, we create a relatively simple page element that allows users to show a list of different SpaceXexternal link rocket and dragon spacecrafts. Here’s what the final result will look like:

SpaceX Page ElementSpaceX Page Element
(click to enlarge)

The custom page element will be available from the Media page elements category:

SpaceX Page Element in the Elements Menu (Media category)SpaceX Page Element in the Elements Menu (Media category)
(click to enlarge)

Also, upon dropping the element onto a page, users will have the ability to adjust the following three settings:

  1. type of spacecrafts to be displayed (rockets or dragons)
  2. number of spacecrafts to be displayed
  3. pagination offset (number of spacecrafts we want to skip when retrieving the data)
Page Element SettingsPage Element Settings
(click to enlarge)

Note that the spacecrafts data will be retrieved from a non-official public SpaceX GraphQL HTTP API, located at https://spacex-production.up.railway.app/external link. Meaning, changing these settings will dictate the variables that will be included in GraphQL queries issued by the page element. More on this in the following sections.

Getting Started
anchor

Quick Set Up

Run the following command to quickly set up the extension in your Webiny project:

yarn webiny extension page-builder/custom-page-elements

Alternatively, continue reading this article to learn how to create this extension from scratch.

To get started, we first scaffold a new Page Builder element extension in the /extensions/spaceXElement folder, via the following command:

yarn webiny extension \
	--type pbElement \
	--name spaceXElement \
	--dependencies graphql-request@^6.0.0,@webiny/ui,@webiny/form,@webiny/validation

Once the extension is scaffolded, in order to start developing, we run the followingwebiny watch command:

# Starts the Admin app locally.
yarn webiny watch admin --env dev
# Starts the Website app locally.
yarn webiny watch website --env dev

Overview
anchor

React Component
anchor

To create a custom page element, the first step is to create a React component that renders it. As we’ll be able to see, this is easily achieved via the createRendererexternal link factory function.

Registering the Renderer
anchor

Via a couple of React components, the next step is registering the renderer React component within our project’s Admin and Website apps.

For this, we’ll be utilizing the admin.tsxexternal link and website.tsxexternal link entry points, that the Page Builder element extension has created for us. Within these files, we’ll be registering the renderer React component via the PbEditorPageElementPlugin and PbRenderElementPlugin React components.

Page Preview In the Admin AppPage Preview In the Admin App
(click to enlarge)

Implementation
anchor

Renderer React Component
anchor

As previously mentioned, in order to create a custom page element, we start off by creating a new renderer React component. To do that, we create the extensions/spaceXElement/src/SpaceX.tsxexternal link file with the following code:

extensions/spaceXElement/src/SpaceX.tsx

As we can see in the code, in order to be able to issue remote GraphQL queries, we’re using the graphql-requestexternal link library, which we’ve specified as our extension’s dependency upon running the webiny extension command in the Getting Started section.

Note that our GraphQL query is called within the useLoader React hook. This is important because, essentially, this enables proper data caching when the page is published. This way, the page element is rendered efficiently, without the need to re-fetch the data each time the page is loaded.

Learn more about the useLoader React hook in a separate article: Loading Data in Page Elements.

Finally, we’ve created a simple unordered list to display the data that has been retrieved. The data is displayed in the form of a list of spacecrafts, with each item containing the spacecraft’s name, description, and a link to its Wikipedia page.

So, with this code in place, we’re ready for the next step, which is registering the renderer React component within our Admin and Website apps.

Admin App
anchor

Registering our custom page element within the Admin app is done via the extensions/spaceXElement/ksrc/admin.tsxexternal link entry point file, via three React components.

The first one is the PbEditorPageElementPlugin component, which is used to register the renderer React component within the page editor. The second one is the PbRenderElementPlugin component, which is used to register the renderer React component within the Admin app, outside the page editor. This is important because pages can also be previewed within the Admin app, for example:

Page Preview In the Admin AppPage Preview In the Admin App
(click to enlarge)

Finally, the PbEditorPageElementAdvancedSettingsPlugin React component is used to register the advanced settings React component within the page editor.

Page Element SettingsPage Element Settings
(click to enlarge)

The following code snippet shows the contents of the extensions/spaceXElement/src/admin.tsxexternal link file:

extensions/spaceXElement/src/admin.tsx

With this code in place, our custom page element should be available within the page editor, and also within the Admin app itself, where pages are previewed.

Before jumping into our browser to see the results though, let’s also register the renderer React component within the Website app.

Website App
anchor

In order for our custom renderer React component to be used in a page on our public website, we need to register it via the PbRenderElementPlugin plugin, via the website.tsxexternal link entry point file:

extensions/spaceXElement/src/website.tsx

And that’s all there is to it. With this code in place, we can now jump into our browser and see the results.

Testing
anchor

With the above steps correctly completed, we should be able to see our custom page element in Page Builder’s page editor and be able to drop it onto a page.

The page element should also be correctly rendered when previewing the page, and also on the public website, once the page has been published.

Conclusion
anchor

In this article, we’ve created a simple page element that retrieves data from a public SpaceX GraphQL HTTP API. We’ve also seen how to register the renderer React component within the Admin and Website apps, so that the page element can be used within the page editor, and also on the public website.

Of course, this is just a starting point. We encourage you to experiment further and create more complex page elements that can be used to create rich and engaging pages for your website.

Additional Examples
anchor