Using React as a Wordpress theme
Tags: react, wordpress
Published: 2019-08-22 17:22:10

---
title: Using React as a Wordpress theme
published: true
description: how to develop a theme on wordpress using react as if you are using create-react-app
tags: React , Wordpress
---

Not so long ago I became a co-organizer for wpBeirut (Wordpress Beirut), a community dedicated for wordpress developers in Beirut-Lebanon.

One thing I realized from the community that the majority depend on plugins to add something on the frontend or to add functionalities like site builder plugins (Elementor and wpBakery)

and some go towards buying a premade theme and use it because it is less of a hassle for them to write php code in the first place

After doing a small survey with the community, majority follow this pattern for several reasons:

* a small freelance project with a medium budget so just install a premade theme with some plugins
* doesn't know how to write php code (writes in another language) or doesn't know how to code at all (totally normal since wordpress can be used by non technical people)
* comfortable writing the frontend with latest technologies (React/Angular/Vue) and not comfortable writing the frontend purely in php and some jquery


even myself I don't prefer to write the frontend in php, not because I hate php or anything but I feel much more comfortable and faster with React

and Gutenberg (a wordpress plugin that uses React to make wordpress's frontend a little bit modern and easier to use) doesn't cut the deal for me

even if you went towards Gutenberg and you created a couple of blocks, you are still stuck with wordpress's frontend 

#so it is time to use wordpress as a headless CMS

when we talk about using wordpress as a headless CMS, ideally we are ignoring the frontend of wordpress and depend only on the REST api that is supported by wordpress

the cool part about wordpress that writing functions that do REST actions is pretty straight forward

here is an example of changing one's email address by sending the old one and the new one

```
add_action('rest_api_init', function () {
  register_rest_route( 'changemyemailman/v1', 'changedatmail',array(
                'methods'  => 'POST',
                'callback' => 'changeme'
      ));
});

function changeme (WP_REST_Request $request) {
	$oldmail = $request['old_mail'];
	$user = get_user_by( 'email', $oldmail );
$userId = $user->ID;
	$args = array(
    'ID'         => $userId,
    'user_email' => $request['new_mail']
);
wp_update_user( $args );
}
```
just send an api call to /changemyemailman/v1/changedatemail with the body holding:

```
{
   "old_email": "john@doe.com",
   "new_email": "john1@doe.com"
}
```

(I am giving this as an example to show how easy it is to create an endpoint on wordpress, but the example above is an absolute security nightmare because you can change an email address of anyone if you knew the original email and the endpoint so you can easily change an administrator's email to yours and take full control of the site)

#Say hello to CORS!

when you start using wordpress as a headless CMS, you will start seeing the new kid in the block

they call him CORS, and sometimes he can be a total brat but most of the time he is trying to help

to keep it short: CORS (cross origin resource sharing) is mainly used when you are requesting for data that is not from the same origin

Before CORS became standarized there was no way to call an API endpoint under different domain for security reasons. This was (and to some degree still is) blocked by the Same-Origin Policy.

you can read more about it here https://www.codecademy.com/articles/what-is-cors

#say again about CORS? 🤔

CORS is a mechanism which aims to allow requests made on behalf of you and at the same time block some requests made by rogue JS and is triggered whenever you are making an HTTP request to:
* a different domain (eg. site at example.com calls api.com)
* a different sub domain (eg. site at example.com calls api.example.com)
* a different port (eg. site at example.com calls example.com:3001)
* a different protocol (eg. site at https://example.com calls http://example.com)

This mechanism prevents attackers that plant scripts on various websites (eg. in ads displayed via Google Ads) to make an AJAX call to www.yourbank.com and in case you were logged in making a transaction using *your* credentials.

If the server does not respond with specific headers to a “simple” GET or POST request — it will still be send, the data still received but the browser will not allow JavaScript to access the response.

If your browser tries to make a “non simple” request (eg. an request that includes cookies, or which Content-type is other than application/x-ww-form-urlencoded, multipart/form-data or text-plain) an mechanism called preflight will be used and an OPTIONS request will be sent to the server.

A common example of “non simple” request is to add cookies or custom headers — it your browser sends such a request and the server does not respond properly, only the preflight call will be made (without the extra headers) but the actual HTTP request the browser meant to make will not be sent.

# the solution: use React in the same origin as Wordpress! 🎉

whenever I talk about this topic to any wordpress developer, he/she face a difficulty understanding this specific part

how can you use React in the same origin as wordpress? 🤔

well the easy part is to remove the default wordpress frontend and use React, right?

Right! but the hard part: how can we do it? 🤔

well, someone was very nice enough to create a create-react-app style cli tool for using React as a wordpress theme

https://www.npmjs.com/package/create-react-wptheme

it does what it says it does: use React as a theme for wordpress while giving you the 'create-react-app' vibe

# cool! but how can we use it? 🤔

pretty simple, go to your themes folder (that is found in your wp-content folder) and type this command in your terminal
```
npx create-react-wptheme [name of your project]
```
similar to how CRA install packages but there is a small setup you should do first

if you go to your themes section inside wordpress, you will find that it is labeled as broken and missing css files

![missing-css](https://thepracticaldev.s3.amazonaws.com/i/dff7fjl6ttku1hepeasi.png)

in your terminal, enter the project (mine is called react-test) then enter inside the react-src folder

then write: 
```
yarn start
```
you will receive this message on the terminal

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/k1mtgmndy1a5kdbag8ol.png)

so go to your themes section and you will see your react theme there

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/x7e5it2prk9dehvwe2z5.png)

press on live preview, you will see a 'restart the nodejs watcher now' message


![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/hgfr1ghqgfs2xbh1ekzd.png)


just start the server!

```
yarn start
```
![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/9jij0eil2xfrhnk0cvqq.png)

tada 🎉

and you will have a live reloader in your terminal so any changes you do, it will refresh to watcher exactly the same way create-react-app does!

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/kdwzaciaid28owlyfvg9.png)

press on the 'activate and publish' button and it will be serving as the theme for your wordpress site

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/3r64tzqsi7tvz354cvca.png)

all under port 8888! and the cool part that you can use the REST api provided by wordpress without getting stopped by CORS!

so if you have pre-existing wordpress site but you need to refresh the frontend, give it a try!

or if you know React and want to use a CMS like wordpress then the sky is the limit!

fun fact: you can use any React library of your choice, as if you are using CRA but it is on wordpress

what I do in this kind of setup: create custom post types and put custom fields on them, then call for those custom posts and show the data from the custom fields in the React application!

hope you enjoyed this post! and let me know what you think about it in the comment section