Using Rails and Vue JS, Part 1



Vue (pronounced as view) calls itself the progressive JavaScript framework. It is designed to be incrementally adoptable. You can use Vue to build user interfaces on a few pages or a few areas of an existing Rails view. You don’t have to throw away existing Rails code.

Vue can also be used as a full-featured framework by using supporting Vue libraries in addition to the core library. This post is about using Vue with an existing Rails application. While we are going to create a new Rails application as an example, we will also create a Rails view and add Vue to it.

This is divided into these sections:

Create a Rails application

We’ll begin by creating a new Rails 5.1 application. Turbolinks works with Vue but we’ll skip it since we’re not going to use it.

rails new vueapp --skip-turbolinks --webpack=vue

We pass --webpack=vue to use Webpack to manage JavaScript code. Rails already has Asset Pipeline for adding JavaScript code, as well as CSS and images. Webpack has been adopted by Rails starting 5.1 to have better support for JavaScript frameworks. You’ll see a lot of tutorials and code that still use Vue with Asset Pipeline but if you’re starting a new application, use Webpack.

When using Asset Pipeline, you put your JavaScript code on app/assets/javascript. With Webpack, you’ll use app/javascript/packs. The rails new command created the packs directory and a few files.

Create a controller and a view.

rails generate controller Pages welcome

Set the welcome action as the root of your app. Edit config/routes.rb

root 'pages#welcome'

Hello Vue

Rails added app/javascript/packs/hello_vue.js, which contains some code. Comment out or delete this code and replace it with the following Vue code.

import Vue from 'vue/dist/vue.esm'

document.addEventListener('DOMContentLoaded', () => {
  var app = new Vue({
    el: '#app',
    data: {
      message: 'Hello Vue!'

This code creates a new Vue app and we pass the el and data options. el is the HTML element that Vue will use. You can see below that this is a div with an id of app.

You might also like:   Rewrite Rules in Nginx

On app/views/pages/welcome.html.erb, you can mix the Vue template code with the existing Rails view.


<div id='app'>
  {{ message }}

The message inside data on the Vue app will appear on {{ message }}.

On app/views/layouts/application.html.erb, add javascript_pack_tag inside head.

<%= javascript_pack_tag 'hello_vue' %>

Start your Rails app with rails s. Go to http://localhost:3000 and you should see


Hello Vue!

You now have Vue working with your Rails application!

This example shows that you can pass the message string from JavaScript to the Rails view using the Mustache syntax {{ message }}. This alone is not impressive but Vue is doing a lot more here. Vue linked the data and the DOM (Document Object Model). When you change the data, the DOM will update automatically.

Let’s take a look at other features of Vue. You can use the same files – welcome.html.erb for the HTML code and hello_vue.js for the JavaScript code. The first code on the following examples (div) goes to the Rails view. The second code (new Vue) goes to the JavaScript file.


v-bind binds the element attributes, in this case title, to the data on the Vue app.

<div id='app-2'>
  <span v-bind:title='message'>
    Hover your mouse over me for a few seconds
    to see my dynamically bound title!
var app2 = new Vue({
  el: '#app-2',
  data: {
    message: 'You loaded this page on ' + new Date().toLocaleString()


v-if toggles the presence of an element depending on its value.

<div id='app-3'>
  <span v-if='seen'>Now you see me</span>
var app3 = new Vue({
  el: '#app-3',
  data: {
    seen: true


v-for goes through each item on an Array.

<div id='app-4'>
    <li v-for='todo in todos'>
      {{ todo.text }}
var app4 = new Vue({
  el: '#app-4',
  data: {
    todos: [
      { text: 'Learn JavaScript' },
      { text: 'Learn Vue' },
      { text: 'Build something awesome' }


v-on attaches a method to event listeners.

<div id='app-5'>
  <p>{{ message }}</p>
  <button v-on:click='reverseMessage'>Reverse Message</button>
var app5 = new Vue({
  el: '#app-5',
  data: {
    message: 'Hello Vue.js!'
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('')

The reverseMessage function goes inside methods.


v-model creates a two-way binding between form input and app state.

<div id='app-6'>
  <p>{{ message }}</p>
  <input v-model='message'>
var app6 = new Vue({
  el: '#app-6',
  data: {
    message: 'Hello Vue!'

While typing text on the text field, the message displayed inside <p> gets updated.

You might also like:   That's Not a Memory Leak, It's Bloat


Rails through Webpacker compiles the packs automatically. This is convenient since we can start using Vue and Rails by just running the Rails server. However, this slows down the response time of the application. Rails installs webpack-dev-server which will serve the JavaScript files that you add on Webpack. On a separate terminal, run



Install the Vue devtools extension or addon for your browser. It’s a big help in debugging Vue applications. Try editing the data using Vue devtools and you’ll see that the DOM gets updated.

What’s Next

The examples on this post are from the official guide. We’ve barely scratched the surface on the Vue framework. We put the Vue code inside our Rails application but we haven’t really integrated the two. Next, we’ll discuss Vue components and integrate Vue with Rails.

Want more posts like this?

What you should do now:


Easy Application Deployment to AWS

Focus on development, not on managing infrastructure

Deploying, running and managing your Ruby on Rails app is taking away precious resources? Engine Yard takes the operational overhead out of the equation, so you can keep innovating.

  • Fully-managed Ruby DevOps
  • Easy to use, Git Push deployment
  • Auto scaling, boost performance
  • Private, fully-configured Kubernetes cluster
  • Linear pricing that scales, no surprises
  • Decades of Ruby and AWS experience

14 day trial. No credit card required.

Sign Up for Engine Yard

14 day trial. No credit card required.

Book a Demo