Wordpress Graphql



Often, it can be inconvenient to query Menus by ID. Since Menu names in WordPress are unique, the name can be used as a unique identifier and we can query for Menus by name using the idType argument like so: Screenshot of a GraphQL Query for a Menu identified by its Name. List of Menu Items. WPGraphQL is a WordPress plugin that adds a GraphQL API to your WordPress site. GraphQL is a query language for requesting information from an API and a protocol for servers that support it. Gatsby uses GraphQL to serve page data. It queries your local WordPress GraphQL schema for all Posts, iterates through each Post node and constructs a static page for each, based on the defined template. For example: After fetching data from WordPress via the query, all posts are iterated over, calling createPage for each one.

  1. Wordpress Graphql 404
  2. Graphql Api Github
  3. Wpgraphql
  4. Wordpress Graphql Acf
  5. Wordpress Graphql React

What is GraphQL?

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:

Wordpress graphql acf
  • 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

How GraphQL could be used from WordPress?

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.

Creating a Single Page Application with React

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.

Data access layer with GraphQL

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.

Navigate first level pages to create the menu

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:

Wordpress Graphql 404

  • 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.

Wordpress graphql react

Querying pages from WordPress

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).

Graphql

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.

Want to know more?

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, websiteowners 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.

For a fun learning & experimentation project, I’ve been building a Dungeons and Dragons character generator. The frontend is built using React JS and deployed to Netlify, and the backend is powered by WordPress and WP GraphQL.

I could have tried using a serverless database such as FaunaDB, but I chose WordPress because of familiarity, what it gives you for free, and it’s flexibility when combined with WP GraphQL. I did however need to build a login system. To do this I created a GraphQL login endpoint, and handled user sessions using Cookies.

Cookies vs JWT

JWT (JSON Web Tokens) can be used to authenticate requests between parties. There is a decent overview of how JWT works here.

A plugin is available for WP GraphQL which handles authentication using JWT and adds a login endpoint. This looked promising, however, the most difficult thing about using JWT in the context of a web based React app is storage of the token. Whilst some articles recommend using localStorage, doing so is not secure—the token could be leaked using XSS.

Don’t store it in local storage (or session storage). If any of the third-party scripts you include in your page gets compromised, it can access all your users’ tokens.

JWT Authentication: When and how to use it

To keep our tokens secure our only option would be to store them in memory. The session would not persist if the browser tab was closed, making it less than ideal.

Graphql Api Github

A better option, and the solution I went with, is using good old fashioned cookies (specifically HTTP Cookies which are inaccessible by JavaScript). I created a new GraphQL route that would set a HTTP cookie after successful login.

Side note: I did find a plugin for WP GraphQL which supports WP cookies, but I encountered browser compatibility (CORS) issues, so ended up rolling my own based on that.

Register a GraphQL Login Mutation

In order to login, we need to register a new endpoint with WP GraphQL. We do this by hooking in to graphql_register_types and adding our new mutation using the register_graphql_mutation function documented here.

We’ll call our mutation loginWithCookies and we’ll use inputFields to define which fields are accepted (username and password), outputFields to define the response, and mutateAndGetPayload to perform the login action:

Wpgraphql

We can use this mutation using a GraphQL query. You can view my usage of the login mutation in the React app here.

Setting the logged-in cookie

When you log in, WordPress sets cookies to track your session. These cookies have a httponly parameter so it is not readable through JavaScript.

I found the easiest way to give the headless site access to cookies was to set an additional cookie.After reviewing this, it doesn’t appear to be needed—previously I had issues with Safari but this no longer seems to be a problem. The regular WordPress login cookie is enough.

It doesn’t work yet though, if we try to login we’ll see a CORS error in the browser:

We need to send some additional headers so the browser does not reject the cookie!

Setting CORS Headers

Wordpress Graphql Acf

The final piece of the puzzle is telling the browser it should accept the custom cookie when logging in from the headless site. We can define headers for our GraphQL routes using the graphql_response_headers_to_send hook.

A detailed explanation of CORS can be found in MDN, as well as docs for allow credentials and allow origin.

Wordpress graphql nextjs

Wrapping up

We’ve now created a GraphQL mutation which accepts login credentials and logs users in using a custom cookie, and we’ve set CORS headers so the browser allows the cookies to be used. Great! We can now hook this up to a login form in the React app.

This is post 1 of 4 in the series “Headless WordPress”

Wordpress Graphql React

  1. Headless WordPress: Cookie Based Login using GraphQL