Page Builder > Extending Functionality
Create a Custom Page Element
Learn how to create a custom page element that can be rendered on pages created with the Webiny's Page Builder app.
- how to create a custom page Builder element
- how to register plugins in Webiny applications
The full code example used in this article is available in our webiny-examples GitHub repository.
Introduction
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 SpaceX rocket and dragon spacecrafts. Here’s what the final result will look like:
The custom page element will be available from the Media page elements category:
Also, upon dropping the element onto a page, users will have the ability to adjust the following three settings:
- type of spacecrafts to be displayed (rockets or dragons)
- number of spacecrafts to be displayed
- pagination offset (number of spacecrafts we want to skip when retrieving the data)
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/. 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
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
React Component
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 createRenderer
factory function.
Registering the Renderer
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.tsx
and website.tsx
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.
Implementation
Renderer React Component
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.tsx
file with the following code:
Note that, in order to be able to issue remote GraphQL queries, we’re using the graphql-request
package, which we’ve specified as a dependency upon running the webiny extension
command in the Getting Started section. Furthermore, for simplicity’s sake, all the code is placed in a single file. Of course, it is possible to organize it across multiple files, if preferred.
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
Registering our custom page element within the Admin app is done via the extensions/spaceXElement/src/admin.tsx
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.
Finally, the PbEditorPageElementAdvancedSettingsPlugin
React component is used to register the advanced settings React component within the page editor.
The following code snippet shows the contents of the extensions/spaceXElement/src/admin.tsx
file:
When it comes to plugin registration, in total, there are three plugins we need to register within the Admin app. The two shown above, plus the previously created PbRenderElementPlugin
plugin. The PbRenderElementPlugin
is required because, as mentioned, pages can also be previewed within the Admin app, outside the page editor.
With all the plugins registered, we’re now ready to give this a try locally in our browser.
Website App
In order for our custom renderer React component to be used upon rendering a published page, we need to register it via the PbRenderElementPlugin
plugin, via the website.tsx
entry point file.
Testing
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
Creating custom page elements is certainly an interesting option when users need more than what the default set of page elements provides.
On the code level, this could be creating completely custom (renderer) React components, including needed external NPM libraries, or even issuing remote HTTP requests to external HTTP APIs in order to retrieve data from standalone external systems.
On the other hand, custom page elements also add additional flexibility by allowing content creators to tweak elements’ settings and, ultimately, allowing them to achieve more with just a single page element.