DEV Community

Cover image for Add Custom Domains To Your Rails App
Zain Butt
Zain Butt

Posted on

Add Custom Domains To Your Rails App

I often saw a lot of apps giving the ability to use our own domain to either access the app or personalise some part of it. For instance, if you want to map your domain/subdomain to an external blogging system Or use your own domain to generate short links.

I was very curious as to how would this work, turns out its not so complicated.


For this to work properly, your user will need to set their website’s custom_domain to iamzain.com in your app. With that in place, the request flow looks like this:

1- A user visits iamzain.com, which points to devtree.app

2- Your app handles the request from the custom domain, routing the request to the #index action in ProfilesController

3- Your controller looks up the user with iamzain.com as the custom_domain and renders it

These instructions are primarily targeted for Rails application but the concept could be ported to any language/framework.


There are a few steps involved, let’s get going:

1- First we will make our application capable of storing the custom domain.

Add a migration to add a column to users table



class AddCustomDomainToUsers < ActiveRecord::Migration[7.0]
  def change
    add_column :users, :custom_domain, :string
  end
end


Enter fullscreen mode Exit fullscreen mode

Create a simple form for users to add custom domain and save it against the user.


2- Once the custom domain is saved, present the user with some CNAME records that they can add to their DNS.

records

Here is how it will work, when the user adds these records to their domain DNS, it will inform the internet to forward any request to our app whenever someone types their custom domain in the browser.

CNAME (canonical name) records helps us with this, rather than redirecting the users it would just forward the request to our app.

From there we would have the access to current host name which would be the domain.


3- Now we will add some code to make sense of the user’s domain.

Add a root route that would point to a controller action, you can name it anything.



get '/', to: 'profiles#index'

class ProfilesController < ApplicationController
  def index
    @user = User.find_by(custom_domain: request.host)

    if @user.nil?
      render 'errors/not_found', layout: 'error' and return 
    else
      render 'profile/show', layout: 'profile_layout'
    end
  end
end


Enter fullscreen mode Exit fullscreen mode

We check for the host name and see if it exists and return relevant profile.

This is the bare bones that we would require to handle custom domain workflow in our app.


Note for Apps running on PaaS like heroku, render or flyio.

These platforms require you to add that custom domain in their settings as well to make sense of any request coming in, so there proxy servers can forward that request to your app. These platforms normally expose public API’s to do so.

Hope you liked it, feel free to ask away any questions you have.


My name is Zain and I am building devtree where developers can get hired without any job search.

I post about my journey, lessons learned and success on twitter and linkedin. You will also find other things on my devtree profile as well.

If you want to learn about working on Startups, Rails and general life advice follow me.

Top comments (3)

Collapse
 
dragocrnjac profile image
Drago

Hey @zainbutt, great post! It will help any intermediate developer get started with custom domains in their Rails app.

I wrote a similar post where I got a bit deeper into the DNS side of things and handling HTTPS and certificates. Could be a good addition to what you wrote here. It's here if you want to check it out: saascustomdomains.com/blog/posts/h...

Collapse
 
matijasos profile image
Matija Sosic

Amazing resource, thanks for sharing!

Collapse
 
zainbutt profile image
Zain Butt

Thanks @dragocrnjac

Great addition, you definitely went technical and deep on this. In my case I didn't have to worry about too much DNS, but just a little bit.