Take Your WordPress Site Further With Vue.js
Tags: wordpress, php, vue, javascript
Published: 2021-03-09 05:18:59

## TL;DR

A 5 minute read? Who has time for that amiright? You can create a microservice with Vue.js and dress it up like a WordPress plugin. Here's a working example of what I'm talking about - https://github.com/stevewhitmore/vue-wordpress-integration-starter

## Background

I recently came across a situation where I had to add some fairly advanced frontend functionality to a WordPress website that I manage. I had a couple options that came to mind right away:

1. Create a custom theme template and shoehorn some jQuery in there to get the job done.
2. Find a plugin that does something similar and shoehorn some jQuery in there to get the job done.
3. Do either option 1 or 2 but with vanilla JS because even though it's installed by default for WordPress [you really don't need jQuery anymore](https://medium.com/hackernoon/you-truly-dont-need-jquery-5f2132b32dd1).

In my experience choosing one of these three options is usually how custom functionality gets added to an otherwise established WordPress installation/theme.

Options 1 and 2 are out the window for me by default nowadays but unfortunately option 3 doesn't work so well when you have a custom business need and complicated logic that goes into the functionality. Applications written in vanilla JS don't scale super well which is why we have frameworks like Angular, React, and Vue among others.

Fortunately for us Vue plays very nicely with existing JavaScript code. I realized I could create a microservice in Vue and drop it into my WordPress installation as a plugin. 

*Surely someone else has had this same exact need as me*, I thought. *I'll find something on DEV.to or Medium or something where somebody figured this out already and I'll just piggyback off of that*. Well past me soon found out how wrong he was. Yes there was some documentation out there but I couldn't find anything where somebody laid out everything for me step by step. Sometimes I like figuring things out. Sometimes I don't have the time, motivation, or energy for such tomfoolery. I'm lazy by nature and in most cases being lazy [works to our advantage as developers](https://dev.to/drm317/the-lazy-developer-5goe).

I didn't have the luxury of being lazy in this scenario and I had to piece it together. That is why, dear reader, I extend to you this gift of not-having-to-because-the-answer-is-out-there-already. You're welcome.


## Step 1: Make the Vue app

A good microservice is decoupled from the code it interacts with. Create a new Vue app outside of your WordPress codebase. I really like their [CLI feature](https://cli.vuejs.org/) so I'd recommend getting that installed if you don't have it already.

```shell
npm i -g @vue/cli
```

Once that's successfully done you'll want to create the Vue project.

```shell
vue create my-awesome-new-app
```
Follow the prompts and get a basic placeholder app generated. This article isn't really about how to create a Vue app via their CLI but [their docs](https://cli.vuejs.org/guide/installation.html) are pretty helpful with this topic.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9vfg7370djdfukaw29p.png)

Now you can work on developing the application outside of WordPress and get it working independently. Once it's in a place where you want to start pulling it into your WordPress site you can move onto the next step.

## Step 2: Do a Bit of Folder Restructuring

From the root of your newly created Vue project create another folder called `app`. Put everything from the root of your project in that folder. Next make two new folders: `plugin` and inside that whatever the name of your app is. In my case it's `plugin/my-awesome-new-app`. It should look something like this:

![new folder structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c3r996tb16e1hvq63tl1.png)


## Step 3: Modify the build script

We're making this app a WordPress plugin. That plugin needs to have a copy of the executables for this app so we'll update the `build` script in our `package.json` file to do the extra step of copying the dist folder to our new plugin folder.

```json
"build": "vue-cli-service build",
```

becomes 

```json
"build": "vue-cli-service build && cp -r ./dist ../plugin/my-awesome-new-app",
```

Now when you run `npm run build` you'll see something like the following:

![build result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y0t1pu6jiv9lhiwx12ll.png)

So now you've got the following contents in your project:

```
|-- app
    |-- [+] dist
    |-- [+] node_modules
    |-- [+] public
    |-- [+] src
    |-- .gitignore
    |-- babel.config.js
    |-- package-lock.json
    |-- package.json
    |-- README.md
|-- plugin
    |-- my-awesome-new-app
        |-- [+] dist
```


## Step 4: Create the Plugin File

Now comes the part where we meld our shiny new Vue app into a WordPress plugin. Create a php file in your `/plugin/my-aweseome-new-app` folder. You'll want the file name to be the same as the plugin. In this case it's `my-awesome-new-app.php`. Here's a revised version of the folder structure table above:

```
|-- app
    |-- [+] dist
    |-- [+] node_modules
    |-- [+] public
    |-- [+] src
    |-- .gitignore
    |-- babel.config.js
    |-- package-lock.json
    |-- package.json
    |-- README.md
|-- plugin
    |-- my-awesome-new-app
        |-- [+] dist
        |-- my-awesome-new-app.php
```

Now you'll want to fill out the new php file with code that
- Provides metadata about the plugin through the comments at the top of the file
- Registers and enqueues the styles and minified javascript for the Vue app
- Creates a shortcode to insert into your WordPress site

It'll look something like this -

```php
<?php
/**
 * Plugin Name:         My Awesome New App
 * Plugin URI:          https://yourdomain/wherever-you-keep-the-app-readme-file
 * Description:         Some great app that I made and it's so great it'll make your life great!
 * Version:             1.0.0
 * Author:              Steve Whitmore
 * Author URI:          https://stevewhitmore.gitlab.io 
 * 
 * Be sure to rename the folder this file is in and this file to match what your plugin will be called. The names must be the same so WordPress knows where to look.
 */

function load_vuescripts() {
    wp_enqueue_style( 'vue_wp_styles', plugin_dir_url( __FILE__ ) . 'dist/css/app.2cf79ad6.css' );
    wp_register_script( 'vue_wp_compiled', plugin_dir_url( __FILE__ ) . 'dist/js/app.010d7631.js', true );
    wp_register_script( 'vue_wp_dependencies', plugin_dir_url( __FILE__ ) . 'dist/js/chunk-vendors.1be0eeb0.js', true );
}

add_action( 'wp_enqueue_scripts', 'load_vuescripts' );

function attach_vue() {
    wp_enqueue_script( 'vue_wp_compiled' );
    wp_enqueue_script( 'vue_wp_dependencies' );

    return "<div id='app'></div>";
}

add_shortcode( 'vue_wp', 'attach_vue' );

// Add the shortcode [vue_wp] to any page or post.
// The shorcode can be whatever. [vue_wp] is just an example.
?>
```

> **Note:** Each time you make changes to your Vue app and build, the files will have newly hashed file names to help with caching issues. Be sure to update your php file with the new file names every time you build as needed to see your changes reflected.

## Step 5: Upload and Activate

Upload the contents of `/plugin/` to your WordPress installation's `/wp-content/plugins` folder. Log into your WordPress admin panel and navigate to the Plugins section. You should see your new plugin waiting to be activated.

![plugin activate](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2lry7uvlg5lvlzol35ft.png)


## Step 6: Insert the Shortcode

Once activated you can either insert the shortcode through template code or by adding it to a page

```php
<?php
/**
 *
 * Template name: Some Template
 *
 */
get_header(); ?>

<section id="main">
	<h2>Some Page About Something Or Other</h2>
	<?php echo do_shortcode("[vue_wp]"); ?>
</section>

<?php get_footer(); ?>
```

or

![shortcode page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/koyxx5nsau2r6mjams18.png)

## Step 7: Rejoice

You did it! 

<img width="100%" style="width:100%" src="https://media.giphy.com/media/pa37AAGzKXoek/giphy.gif">

That wasn't so bad was it? If it was please feel free to let me know how I can make this tutorial easier to follow and I'll get it updated. Otherwise please don't hesitate to ask me any questions!