77

How can I route /foo to display /public/foo.html in Rails?

Aen Tan
  • 3,305
  • 6
  • 32
  • 52
  • Probably duplicate: http://stackoverflow.com/questions/1146624/how-to-do-static-content-in-rails – Syed Aslam Apr 12 '11 at 06:36
  • 4
    Syed, it's not a dupe of that question since that question is referring to maintaining the layout, etc. – William Denniss Feb 12 '12 at 04:41
  • 1
    Just as a note, if you're trying to set up a static welcome page or something rails will automatically show `public/index.html` if nothing else is specified. – kingsfoil Dec 01 '17 at 03:35

3 Answers3

111

You can do this:

Add this, into your routes.rb file.

match '/foo', :to => redirect('/foo.html')

Update

In Rails 4, it should use "get", not "match":

get '/foo', :to => redirect('/foo.html')

thanks Grant Birchmeier

Community
  • 1
  • 1
Arkan
  • 6,196
  • 3
  • 38
  • 54
  • 2
    If you're redirecting to an asset in public, you probably want `redirect('/foo.html')` (without the /public) – bendytree Aug 17 '11 at 20:54
  • 11
    In Rails 4, it should be `get '/foo', :to => redirect('/foo.html')` ("get" instead of "match"). – Grant Birchmeier Jul 23 '13 at 13:44
  • 33
    Is there a way to do this where it sends the content of the file rather than redirecting? – Emily Aug 06 '13 at 20:43
  • 11
    @Emily I would recommend you to use a controller to send the content of a file.See this link: http://apidock.com/rails/ActionController/Streaming/send_file . However, something like this should work. match "/foo", :to => proc {|env| [200, {}, [File.open(Rails.root.join('config', 'routes.rb')).read]] }, via: :get – Arkan Oct 01 '13 at 07:31
  • 1
    Deploying to Heroku, this yields a redirect loop. Perplexing it's that complex to get a landing page to work in rails.... – matanster Nov 02 '13 at 19:38
  • @Arkan +1 for mentioning the name of Grant. – Abhinay Dec 02 '15 at 18:47
  • @Arkan +1 for a method that works well for domain control validation (DCV) on Heroku when applying for new SSL cert – xaphod Feb 15 '17 at 21:25
19

This can be done without triggering a redirect. Follow the steps further down to be able to route static files in config/routes.rb as shown in this example:

# This route will serve public/index.html at the /login URL 
# path, and have a URL helper named `login_path`:
get "/login", to: static("index.html")

# This route will serve public/register.html at the /register
# URL path, and have URL helper named `new_user_registration_path`:
get "/register", to: static("register.html"), as: :new_user_registration
  1. Install the rails-static-router gem: https://github.com/mufid/rails-static-router#installation
  2. Restart app (first bin/spring stop to be sure app is completely reloaded).
  3. Start using the static(path) method in your config/routes.rb.
Eliot Sykes
  • 9,616
  • 6
  • 50
  • 64
  • 4
    Just in case someone trying to use this for Rails 5, the syntax must be changed. Omit the second parameter, so it should be only `ActionDispatch::FileHandler.new(Rails.configuration.paths["public"].first)` – waza Apr 04 '17 at 04:38
  • Link to [ActionDispath::FileHandler](https://github.com/rails/rails/blob/ffa13e9d4fdd0684844ad72000c6e949d565dd35/actionpack/lib/action_dispatch/middleware/static.rb#L16) and link to the [Redirect – guzart Apr 04 '17 at 06:16
  • 2
    Don't ask me why, but this blew up for me in production unless I have `require 'action_dispatch/middleware/static'` at the top... – dain Oct 17 '17 at 20:14
  • This works nicely with a React app that will be, optionally, served by Rails server, like Puma. Just add catch all routes for `GET` and `POST` to point to `static("index.html"). – Rael Gugelmin Cunha Mar 16 '23 at 10:38
1

E.g in Rails 4 add the following route:

get '/example', :to => redirect('example.html')

Also you need to enable static files from the 'public' directory in your configuration:

config.serve_static_files = true

OR

config.serve_static_assets = true

Also you might need to provide your public directory as root in NGINX configuration.