How to create a single page application with React consuming Wordpress data with GraphQL
WordPress is definitely the most used platform on the internet. 30% of all websites on the internet are powered by WordPress. From a developer perspective this may not be the most loved approach to create a website. Having in mind how many new tools are created to make our daily work more productive, innovative and enjoyable there is definitely a gap here. Although from a website owner standpoint things are a little different. WordPress probably offers a good deal, it has an easy to use CMS, it is fast to setup and most authors and editors feel comfortable with it.
Is there any alternative to create a modern website using WordPress? Luckily there are some alternatives. The idea of this post is to present one approach to create a Single Page Application consuming WordPress data, relying on modern tools such as React, GraphQL and Webpack.
GraphQL is a spec released by Facebook in 2015. Below there is a simple image that compares GraphQL and an API REST.
The beauty of a GraphQL data layer is that clients are able to access data as they need it. Instead of requesting information from several endpoints in order to create a UI component, they just need to request data from a single endpoint and specify how that data will be formatted. GraphQL is a good replacement of a REST API Gateway pattern implementation used in microservices.
There are three basic components to understand in GraphQL:
Schema: Strongly typed schema. For each data entity, it defines the type of each single field.
Queries: Specified in a JSON like format, where several data entities could be related. Without the need to fetch data from the server several times.
Results: Query results take the format specified in the query.
There are several resources to understand how GraphQL works. If you want to read more I suggest these resources:
GraphQL official documentation
Apollo has an awesome blog that covers different topics related to GraphQL
Relay official documentation
There is a plugin called WPGraphQL. “A free, open-source WordPress plugin that provides an extendable GraphQL schema and API for any WordPress site.”
This nice plugin allows to access almost all WordPress data (Posts, Categories, Pages, Users, Media files) and it also allows to extend its schema to include Custom Types and 3rd party plugins. Even though the plugin is still under active development, it can be used to create some basic websites and proofs of concepts. To setup the plugin in your WordPress instance follow the instructions here.
In order to create a new presentation layer for a WordPress website there are some things to sort out like the data access layer, routing (it would be awesome to have a similar structure to WordPress URLs), single page navigation for pages, children pages and posts. Let’s cover them one by one.
In a front-end application, even though a regular HTTP request could be used to get data from a GraphQL server, it is highly recommended to use a GraphQL client because of the recurrent challenges it brings. Generally in any application you would need to integrate it with the front-end framework, use caches in order to speed things up, paginate large sets of data easily, etc.
That’s where Apollo Client (a GraphQL client) comes in handy. I decided to use Apollo over Relay, even though WPGraphQL is implemented following the Relay spec in the back-end, because of the following reasons:
Extremely easy to setup
Front-end framework agnostic
Flexible and adaptable to any GraphQL schema
The code below shows an example of how easy it is to setup Apollo Client to start querying the GraphQL server.
In a real WordPress website, the menu would be defined using the Menu widget. Currently WPGraphQL doesn’t support getting this data. There are some alternatives to solve this issue like extending the GraphQL schema, hard-coding the menu on the front-end app or implementing an auto-generated menu getting all the first level pages. Let’s take a look at how this could be implemented using the latest approach.
There are some lines worth mentioning in this snippet:
Line 36: graphql is a Higher-Order Component that wraps UI components. It is in charge of fetching data and making the query result accessible through the component props.
Line 8: The HOC mentioned above injects some interesting variables inside props.data.
loading: returns true or false depending on the state of the fetching process.
error: not used in the example, in case there is an error this property contains the details of it.
pages: it’s the result data of the query. The name corresponds to the query (see line 38).
Lines 44 – 49: The query only specifies two fields (title and slug), which are used in the React component.
Line 52: On this example there is another HOC used withRouter. It gives the chance to get React Router 4 location information.
Menu is in place! Now it’s time to display the WordPress page with React when the user clicks on the nav. Since the main idea is to re-use all WordPress data, HTML pages are going to be fetched from the GraphQL server and injected in the React Page component. This can be seen in the example below (lines 15 – 17).
In this case the data retrieved from the server is raw HTML, so it’s possible that there are some links (or anchor elements) as part of the markup. Clicking on a regular anchor element will take the user outside the React app. To ensure a single page experience these links need to have a handler aware of react router and navigate the page using this library. In line 22 the React life-cycle method componentDidUpdate() is used to get all anchor elements and override the click functionality.
Using React, Apollo Client and the plugin WPGraphQL there is a new way to create (or reuse) legacy WordPress websites. The alternative approach described here benefits developers who want to use and take advantage of cutting-edge technologies, website owners that want to use tools they already know and don’t want to invest time and effort on migrating to another platform, website users who want fast and enjoyable experiences.
If you want to try this approach with your already existing WordPress instance here’s the repository with all the front-end code: wp-react-graphql.