Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails not rendering public/index.html file; blank page in browser

I have a problem with my Rails + React app when I deploy it to Heroku. The React client is inside a client/ directory of the Rails app. Due to using react-router, the Rails server needs to know to render the index.html from the React build. When I deploy the client on Heroku, a script copies the content from client/build/. to the Rails app's public/ dir.

Now here is the problem: when my route detects a path like example.com/about it tries to render public/index.html. Here is the method:

def fallback_index_html
   render file: "public/index.html"
end

However, the contents from this file are not sent to the browser. I get a blank page. I have added a puts "hit fallback_index_html" in the method and confirmed that this method is being hit. I have also opened the file in puts each line to confirm the file has the required html (this is what appeared in the logs from that puts and what SHOULD be sent to the browser):

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <link rel="manifest" href="/manifest.json">
    <link rel="shortcut icon" href="/favicon.ico">
    <title>Simple Bubble</title>
    <link href="/static/css/main.65027555.css" rel="stylesheet">
</head>

<body><noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <script type="text/javascript" src="/static/js/main.21a8553c.js"></script>
</body>

</html>

The most recent fix I tried was going into config/environments/production.rb and changing config.public_file_server.enabled to true. This did not help.

like image 984
stevenpslade Avatar asked Jan 07 '18 18:01

stevenpslade


1 Answers

I'm using Rails API, so my ApplicationController inherits from ActionController::API instead of ActionController::Base.

From Rails API docs it says:

The default API Controller stack includes all renderers, which means you can use render :json and brothers freely in your controllers. Keep in mind that templates are not going to be rendered, so you need to ensure your controller is calling either render or redirect_to in all actions, otherwise it will return 204 No Content.

Thus Rails API only cannot render HTML! The following allowed me to render the html without including everything from ActionController::Base.

class ApplicationController < ActionController::API
  include ActionController::MimeResponds

  def fallback_index_html
    respond_to do |format|
      format.html { render body: Rails.root.join('public/index.html').read }
    end
  end
end

The reason I am including ActionController::MimeResponds is to have access to the respond_to method.

My Rails application now renders index.html from my public directory when a subdirectory is hit and my React client / react-router takes over from there.

like image 152
stevenpslade Avatar answered Nov 05 '22 09:11

stevenpslade