DEV Community

Using Vue in WordPress

Lisa Armstrong on April 03, 2019

Like peanut butter and jam sometimes two good things are even better together. In this tutorial I'll show you how to use Vue in a WordPress site....
Collapse
 
shamsail profile image
shamsail

Hi Lisa,
I need an help regarding this enqueue problem.
I have 3 folders in my dist folder after build vue app. 1)js 2)css 3)img . I have successfully enqueued the scripts and styles in my wordpress plugin by using wp_enqueue_script & wp_enqueue_style.
The problem that I'm facing is that I am not able to add/enqueue the 3 folder of img in which I have my image assets that are being used for plugin.
Let's make it simple, generate a default simple vue app and run in wordpress. After enqueue, it'll give js and css but it'll not show the vue image(logo) .

Collapse
 
workingwebsites profile image
Lisa Armstrong

I assume you're setting this up as a plugin. If so, you can reference your images through the plugin url.
developer.wordpress.org/reference/...
That will give you the path to images.
Hope this helps.

Collapse
 
shamsail profile image
shamsail • Edited

Hi,
Thanks for your reply. I have tried this already and it didn't work for me. Also, I had tried by changing paths and folders but nothing seems to work in case of images.

These line of codes are working perfectly with js and css of vue app.

wp_register_script('wpvue_vuejs', plugin_dir_url( FILE ).'dist/js/app.js', [], '1.0.0', true);
wp_register_script('wpvue_vuejs1', plugin_dir_url( FILE ).'dist/js/chunk-vendors.js', true);

wp_enqueue_script('wpvue_vuejs');
wp_enqueue_script('wpvue_vuejs1');
wp_enqueue_style('wpvue_css1', plugin_dir_url( FILE ).'dist/css/app.css', true);

I tried for image source like this but it's not working at all.
plugins_url( 'dist/img/logo.png', dirname(FILE) );
plugins_url( 'dist/img/logo.png', (FILE) );

FILE

Thread Thread
 
workingwebsites profile image
Lisa Armstrong

The issue could be where your /img/logo.png file is in Vue.

As I understand it, the dist folder is a compilation of .js, .css files compiled by Webpack .
Webpack ignores image files and won't compile or put them in the /dist/ folder.

Bottom Line: Your image folder may not be landing in the WP plugin file.

The way around that is a 'public' folder.
see: cli.vuejs.org/guide/html-and-stati...

Try putting your image folder under the public folder (/public/img/logo.png) and tinker around with the path until it works.
To test, compile, upload to WP and check the plugin directory to see if the file is there.
If it's there, but not showing up -- that means it's uploaded, you just need to adjust the path to it.

Hopefully that gets you going the right direction.

Collapse
 
noelmc3 profile image
NOTB

Hi Lisa,
Your article is exactly what I was hoping to find on the internet, thank you so much for this.

Now I have a question.. How do I print WordPress/PHP values using vue js.

For example, in a blog page, I may use Vue to generate the HTML template & the interaction aspects.. but I would like the actual values in the template to be WordPress values such as the_title(); the_excerpt (); and so on..

How do I accomplish this?

Collapse
 
workingwebsites profile image
Lisa Armstrong • Edited

Good question!

I think your best approach would be to set up a component, and pass the the_title(); etc. in as a prop (variable).

See: vuejs.org/v2/guide/components.html
This will guide you through making a component.

Passing props (variables into your components):
vuejs.org/v2/guide/components.html...

In the end, you'd end up with something like..
in vuecode.js

Vue.component('wp-vue-title', {
  props: ['title'],
  template: '<h3>{{ title }}</h3>'
})
Enter fullscreen mode Exit fullscreen mode

In your template:

<wp-vue-title title="<?php the_title(); ?> "></wp-vue-title>
Enter fullscreen mode Exit fullscreen mode

Note: In the example tutorial, it adds a shortcode.

In your case, you probably wouldn't need it, since it sounds like you're doing this through the template. Shortcodes work better on the text side.

Good luck!

Collapse
 
rockykev profile image
Rocky Kev

Hey Lisa - thanks for this post! Got it up and running immediately by the end of the tutorial. Thank you!

One suggestion, and this is totally opinionated, so you can take it with a grain of salt - cleaner naming of functions/scripts/variables. There's a bit of redundancy, and I do believe in naming things after their actions. Again, just my opinion.

Collapse
 
chrisjimallen profile image
Chris Allen

This is a fantastic guide. I've built several VueJS apps using the Nuxt framework, but I had a requirement to embed some Vue into a WordPress page. Compiled NuxtJS apps do not play well with WordPress, but this is ideal. Great idea to package it as a plugin.

Collapse
 
dgmann profile image
DGMANN • Edited

Hey Lisa!
Thank you for your great inspirational article. I extended it a little bit: dev.to/paloma/vue-application-as-a...

Thank you, Paul!

Collapse
 
shomalikhashayar profile image
Khashayar Shomali • Edited

Hi Lisa, I write a headless WordPress theme with Quasar framework(Vuejs) and when I build the app the images are not load, but load correctly on localhost (quasar dev), Why?

Thanks for your help.

On XAMPP and real host:
image

On Quasar localhost:
image

Collapse
 
ariesalma1 profile image
Arie

What would be the implication of simply putting the CDN link in the header file , then just use it wherever I want? Honestly after years w WP, trying bypassing all the registering code etc never caused me problems.

Collapse
 
workingwebsites profile image
Lisa Armstrong

You're right, technically you don't have to register them, but it is a recommended practice to manage scripts and dependencies.

From WordPress:
"the main purpose of the register functions is to allow you to simplify your code by removing the need to duplicate code if you enqueue the same script or style in more than one section of code."

If you were using your Vue plugin in a number of areas, it would be handy. It would make the plugin more standalone, and not dependent on a line of code in the header.

Collapse
 
lopher profile image
lopher

Hello excellent article, just what I was looking for, a question if you can enlighten me, how should I do so that when changing pages I do not reload the navigation screen.

Best regards from Argentina,Hernán lopez Ocampo

Collapse
 
workingwebsites profile image
Lisa Armstrong

I'm glad you found the article helpful!

I'm not sure what you mean by not reloading the menu bar.

Do you want to change the content of the page, but not the menu bar etc.?

If so, you would probably use WordPress's REST API to get the content through Vue, and change it that way.

The trick is how to navigate from one page to another.

There are tutorials out there that may help. Try searching for 'wordpress, headless api, vue'. That may help.

Collapse
 
abrahambrookes profile image
Abraham Brookes

Great walkthrough. What if I want to compile my Vue app using webpack? In the article you say that we need to load the vue library before the DOM loads, and then our vue app after the DOM has loaded. This would mean that we can't bundle vue together with our app code, is that right?

I'm fiddling with it and my vue bundled code is loading, but it's not mounting onto my #app element...

Collapse
 
workingwebsites profile image
Lisa Armstrong • Edited

The key is to make sure everything is loaded so it can work.

That means:

  1. Vue is loaded so your app will work.

  2. The Dom element is loaded so your app can attach to it

  3. The app is loaded so it works.

Generally in Wordpress, scripts are loaded in the head, before the Dom.

This is ok for loading Vue, because it doesn't need the Dom.

However, the app should be loaded after the Dom, so it's best to put it in the footer.

That means if you are loading the two together as one package, put that in the footer since it needs the Dom.

Does that make sense?

Collapse
 
abrahambrookes profile image
Abraham Brookes

Yep makes sense, turns out it was my webpack config, I opted to use laravel mix instead and problem solved! Thanks for the article.

Collapse
 
abrahambrookes profile image
Abraham Brookes • Edited

What about using images from your plugins directory? When using <img :src="require(path/to/image)" />, the image is moved to an 'images' folder in the plugins' root directory, but the image path is compiled to /images/image.png, which, when loaded in the wordpress plugin translates to the absolute URL www.domain.com/images/image.png - and that's incompatible with the wordpress folder structure.

I can use an absolute URL that accesses my plugins folder from the site root (ie: <img src="/wp-content/plugins/my-plugin/images/image.png" />) but I would prefer not to do that because this component needs to work with different environments and potentially different plugin names, I don't want to shackle it to one path.

I'm probably going to write a little filepath utility in here somewhere, but maybe you already have a solution for using images in your vue-wordpress plugin?

Collapse
 
workingwebsites profile image
Lisa Armstrong

For that, use the plugin_dir_url().
codex.wordpress.org/Function_Refer...

The code would be something like:
plugin_dir_url( __FILE__ ) . 'images/foo-picture.jpg';

This means the plug-in can be anywhere on the site, but it will still find the 'images' directory in your plug-in folder.

Note: This is a PHP function, so if you're including it in JavaScript (Vue), allow for that.

Ex. <img :src="<?php echo plugin_dir_url( __FILE__ ) . 'images/foo-picture.jpg'; ?>" />

Collapse
 
edo_begagic profile image
Edo Begagic

Thank You! This is exactly what I needed. You're great! :)

Collapse
 
johndoudou profile image
johndoudou

Thanks a lot for putting that up.
Helped me tremendously as a beginner in the wordpress development ecosystem ;)

Collapse
 
hvaandres profile image
Andres Haro

Hello Lisa,

I'm working on a website, and I would like to add some extra text to my site. However, I'm using woocommerce and WordPress, and I'm pretty new to this javascript library. Do you have any idea of how I can create a plugin that allows me to override any text from the website?

As an example: I'm currently building an eCommerce site yournextfence1.wpengine.com/shop/s... & I would like to add a word ("Quantity") below the price.

If you have any ideas or recommendations, I would like to hear them.

Collapse
 
blackdemon7 profile image
Hidayet Elitok

Thanks for your share, Is this theme editable? a friend of mine ask me for a website but in Wordpress and he wants to edit it later than when I finished the site.
I don't know how to write a Wordpress theme ı just know vue and

Collapse
 
jaycb3 profile image
Jay

Great article! I look forward to reading more from you.

Collapse
 
kojint profile image
Thabang Chukura

Great article Lisa, and your answers to other commenters questions set me on the right path 🙌🏾

Collapse
 
mzerterungwa profile image
mzerterungwa

Thank you for the post Lisa. How can I pass a wordpress PHP variable from wp-vue-tutorial.php into the vue app instance in vuecode.js?

Collapse
 
oglenas profile image
Jon Dewitt

A bit late, but I believe the correct solution to this question would be to utilize wp_localize_script, which lets you pass php values to a given script.

developer.wordpress.org/reference/...
pippinsplugins.com/use-wp_localize...

Collapse
 
workingwebsites profile image
Lisa Armstrong


Hmmm, very good question!

Two things to remember:

  1. PHP writes the HTML file on the server side. That file is passed to the browser where the JavaScript is run.
    That means you need to output the PHP variable so it shows up in the HTML file in the browser. Then Javascript can deal with it. A simple $your_var in the right place will do.

  2. Vue is just Javascript and your Vue code is really a Javascript object.
    That means (generally) you can access it anywhere within JavaScript.

In the example, the object is called 'app'

var app = new Vue({
...
})

That means 'app' can be accessed on the Javascript level.
If you were to run ' console.log(app) ' you would see the object, it's data etc.

Therefore, you could change a value in ' app ' from the Javascript level.

Something like:


 app.message = 'Bonjour Vue';

That means, if you can output something like:


 app.message = '[ php var here ] Vue';

It should work.

The trick is where to add the code in the WordPress platform.

In this example, you're outputting the div, so try adding it there.

Try:

function func_wp_vue(){
  //Add Vue.js
  wp_enqueue_script('wpvue_vuejs');
  //Add my code to it
  wp_enqueue_script('my_vuecode');

  $message = 'Bonjour Vue';

   //Add script 
  $str=""
   ."app.message = 'Bonjour Vue'"
   ."";

  // Display the results
  $str .= ""
    ."Message from Vue: {{ message }}"
    .""

  //Return to display
  return $str;
} // end function

I wouldn't be surprised if WordPress has an issue with a script tag in the middle of things, but try it and see if it works.

Let me know how it turns out. I'm curious to see how this can work.

Collapse
 
belgarat profile image
Marco Brunet

Interesting article. Clean code, good explanation and very useful. An excellent scaffold to start with.

Collapse
 
workingwebsites profile image
Lisa Armstrong

Thanks Marco!

Collapse
 
akashkaintura profile image
AKASH KAINTURA

I have some problem because I have created the Vuejs components but they are not rendered in the WP.

Collapse
 
lastmiles profile image
Mohsen Bakhshande

thank you for your great post @workingwebsites

Collapse
 
workingwebsites profile image
Lisa Armstrong

Thanks Mohsen!
I hope you found it useful.

Collapse
 
tadeubdev profile image
Tadeu Barbosa

You had help me a lot! Thanks for this article!

Collapse
 
limitcracker profile image
Ioannis Gyftakis

Hi, can you please share tips on how to import Axios and Quasar along with those?

Collapse
 
workingwebsites profile image
Lisa Armstrong

You should be able to import the Axios and Quasar files the same way you imported the Vue files by using wp_enqueue_script.

Try using the same code in the tutorial for enque-ing the scripts, only with the proper path, and change the name of the function and handle (first variable in enque)

developer.wordpress.org/themes/bas...

Tr

Collapse
 
aminsbd1 profile image
aminsbd1

its SEO friendly for search engine if Wordpress theme build up with vuejs?

Collapse
 
belgarat profile image
Marco Brunet

Hello.
I have a problem,
if I use the shortcode with attributes:

[wpvi title='vue title']

it works if inside an article or page, but the attribute 'title' is ignored if inserted in a widjet.

Collapse
 
workingwebsites profile image
Lisa Armstrong • Edited

Short codes are meant for pages and posts. Widgets are a different thing.

You can use short codes in widgets, but you have to tell Wordpress to parse them properly.

To get the short code to run in a TEXT widget, try adding the following code to the same file you set up your short code in:

add_filter('widget_text', 'do_shortcode');

More info: wpsites.net/wordpress-tips/enable-...

developer.wordpress.org/reference/...

codex.wordpress.org/Plugin_API

Collapse
 
dgmann profile image
DGMANN • Edited

Hi Lisa,
thank you for your great inspirational article! I extend it a little bit: dev.to/paloma/vue-application-as-a...

Thanks!