Everybody loves single page apps, but paths containing a pound sign ("#") are a little odd. This is why I like using the History API in my EmberJS powered apps.
Turning on History API in Ember is just the matter of switching an attribute. But on the backend side, your server does not know that incoming paths are meant to be interpreted by your Ember app, not by the server. In larger deploys with a load balancer, you can setup rules to redirect API traffic (e.g. paths containing /api/…
) to the backend server, and other traffic to the asset server. But if you're using a smaller setup, like a Heroku deployed app, it's easier to fix right in the Rails app with the Rack::Rewrite gem, as long as you namespace your API. Here's how to do it:
First, add these two gems to your Gemfile and run bundle
after that:
gem 'rails_12factor', group: :production # static file serving on Heroku
gem 'rack-rewrite' # for the actual rewriting
Then, add the following section to your config/application.rb
:
config.middleware.insert_before(Rack::Runtime, Rack::Rewrite) do
index_file = Rails.root.join('public', 'index.html').to_s
send_file(/.*/, index_file, if: ->(rack_env) {
rack_env['PATH_INFO'] !~ /^\/api.*$/
})
end
This will direct all /api/…
to the backend, all other paths are served by your Ember app in the index.html
file. Static files will still be served, though, no matter the path.
This means that your JS app must be contained in the public folder of your Rails app. If you are using a build tool like Ember App Kit, this is easy to achieve:
grunt dist && rsync -av --delete dist/ ../backend/public
Run this from your JS app's folder, with ../backend/public
being the path to your Rails app's public folder.
I hope you found this useful. :)