rails5 APIモードでindex.htmlを配信するための方法をまとめました。
前提
-
rails5.1.2
を利用。 - nginxやCDNを使わずにrails内でソース管理したい。
- URL設計も
routes.rb
で行いたい。
[2020.5.10追記]
render file: パス指定
により動いているものだと思ってましたが、私の勘違いでした
URLと公開ディレクトリを一定のルールで構成すれば、railsのmiddlewareが規約通りにサーブしてくれるようです。
config.public_file_server.enabled
がtrueに設定されていると、publicディレクトリ以下に置かれているすべてのファイルをwebサーバにマウントします。そして、一定のリクエストURLルールにしたがって、publicディレクトリ配下のファイルをレスポンスしているとのことです。例えば、public/about.html
が存在していればhttp://localhost:3000/about
のリクエストに対して反応します。
詳しくは@daido1976さんのコメントをご覧ください。
APIモードでhtmlを配信する
静的ページ専用のコントローラーを用意する。
renderメソッドにfile
キーを明示して静的ファイルのパスを直指定する。
class StaticPagesController < ApplicationController
def index
render file: 'public/index.html'
end
end
class ApplicationController < ActionController::API
end
routes.rb は以下で検証した。
match '*all', to: 'static_pages#index', via: [:get]
root 'static_pages#index'
get '/index', to: 'static_pages#index'
(寄り道)fileをつけなくても良いパターン
ルートで紐付けたcontroller#actionだとfile
キーを付けなくてもいける。
html1枚だけ配信したいケースならこれで事足りる。
root 'static_pages#index'
class StaticPagesController < ActionController
def index
render 'public/index.html'
end
end
(注) render file:
をrender
だけにしている。
パス指定すると、renderだけだとviews
配下を見にいくので、ActionView::MissingTemplate
が発生する。
get '/index', to: 'static_pages#index'
同上
結果
Missing template public/index.html
with {:locale=>[:ja], :formats=>[:html], :variants=>[],
:handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}.
Searched in: * "(...)/app/views"
SPAが動いていない時のケア
不幸にもSPAが管理しているURLなのに、ブラウザが拾ってサーバにGETリクエストを飛ばしてしまうケースは発生する。
- ブラウザのアドレスバーに直接入力した
- ユーザーがブラウザのキャッシュをクリアした
- 特定のURLをいつものwebサービスのようにブクマするなりシェアした
SSR(ServerSideRedering)をしていればまた話は変わるが、そうでなければ以下のようにケアしておく。途中に置くと以降のルートに流れなくなるので、末尾に記載する。
get '*path', to: redirect('/')
(追記)SPAのURLのままシェアする方法を別記事でまとめました。
他のhtmlファイル
サイト紹介のためのabout/contactらも同じように配信できる。
get '/about', to: 'static_pages#about'
get '/contact', to: 'static_pages#contact'
他のJSファイルやCSSファイル
- ルート直下に
public/assets
フォルダを用意するなり。 - フロントでビルドする
- ビルドしたファイルをコピーする