2

I'm currently working on a application with a Ruby on Rails backend and Vue.js frontend. It's a single page application. I'm using the webpacker gem to build my main JS file.

I've added vue-router and and a couple frontend routes. I'm able to navigate using <router-link> which correctly renders the appropriate component. What I can't figure out is how do I setup my frontend routes so that someone can directly navigate to a URL without hitting my Rails routes.

For example if I type /sample-route I'd like to hit my Vue.js route and not my Rails route. I still want to be able to make API calls to my Rails routes as well. For example /api/users.

3 Answers 3

7

My problem was solved by adding <router-view></router-vew> into my main Vue.js component.

Here's my rails routes file as well:

Rails.application.routes.draw do
  namespace :api do
    # api routes here
  end

  root 'application#index'
  get '/*path', to: 'application#index' 
end
Sign up to request clarification or add additional context in comments.

Comments

1

Depending on how many routes you have, you can add your Vue routes to routes.rb and send them to your root Vue application route. e.g. Webpacker is rendering your js pack with controller#action vue_controller#app. Your Vue app router uses /user/profile. In routes.rb, add a route:

get "/user/profile" => "vue_controller#app" # <- The controller action rendering your Vue pack

If it seems unmaintainable to redefine every Vue route in routes.rb, you may want to look into a universal fallback route that sends them to the vue app controller action. As long as you don't change the route, but just respond with the Vue controller action, the Vue router will take care of rendering the right components for that route when the page loads.

In Rails 4, you can use something like the answers in this SO question to help you out with setting up a "catch-all" route Rails catch-all route.

EDIT: Using a catch all route does lead to some problems with 404's. If the user requests a route that doesn't exist, the Rails app will still send them the Vue pack. To fix this, you would need to add some unknown route handling in your Vue router to render something like a 404 page.

2 Comments

Thanks for your help Mando. I added what solved my problem below.
@nflauria I see you went with the catch all route I suggested. As I mentioned, be careful when handling 404's. Make sure that your Vue router has a backup catch all route if you try to access a route that doesn't exist.
1

There is one more approach which will be useful and handles sub-routes as well (having separate vue apps per page in a single rails app):

routes.rb

Rails.application.routes.draw do
    # this route entry will take care of forwarding all the page/* urls to the index
    get 'page_controller/*path', to: 'page_controller#index', format: false
end

Additionally, please handle the api and index routes separately based on the design.

vue-routes.js

const router = new VueRouter({
  mode: 'history',
  base: '/page_url',
  routes: [
    ...
  ]
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.