To use subdomains locally in Rails, set the hosts explictly or update the top level domain length.

Routes file with the app. subdomain constraint:

# config/routes.rb
Rails.application.routes.draw do
  root "marketing#index"

  constraints subdomain: "app" do
    get "/", to: "posts#index"
  end
end

Option 1: Set hosts

# config/environments/development.rb
Rails.application.configure do
  config.hosts = ["app.example.localhost", "example.localhost"]
end

# Add hosts to your /etc/hosts file
127.0.0.1 app.example.localhost
127.0.0.1 example.localhost

Option 2: Update the top level domain length

# config/environments/development.rb
Rails.application.configure do
  config.action_dispatch.tld_length = 0
end

# Add hosts to your /etc/hosts file
127.0.0.1 app.localhost

Test Setup

minitest

# test/application_system_test_case.rb
require "test_helper"

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  def setup
    Capybara.app_host = "http://app.localhost"
  end

  driven_by :selenium_chrome_headless, using: :chrome, screen_size: [1400, 1400]
end


rspec

# This file is copied to spec/ when you run 'rails generate rspec:install'
require "spec_helper"
ENV["RAILS_ENV"] ||= "test"
require_relative "../config/environment"
require "rspec/rails"


Capybara.app_host = "http://app.localhost"

RSpec.configure do |config|
  # ...other config
end

To test another subdomain, set the Capybara.app_host before a test block.