How to Add a Custom Domain to Your App: Step-by-Step
Step-by-step guide to adding a custom domain to your app. Learn DNS configuration, CNAME vs A records, verification, and troubleshooting. 30-minute setup time.
- Adding a custom domain takes three steps: claim it in your hosting platform's dashboard, update DNS records at your registrar, and verify it works within 30 minutes.
- Use CNAME records for subdomains (app.example.com); use A records only for root domains if your registrar supports CNAME flattening, because A records break when platforms update infrastructure.
- DNS propagation typically takes 5-30 minutes globally; use MXToolbox or whatsmydns.net to check if your records are live.
- Most setup failures come from typos in DNS records, TTL cache issues, or SSL certificate delays; these resolve themselves in 5-15 minutes.
- Ship includes custom domain setup with automatic SSL and guaranteed stability, avoiding the infrastructure-update failures that affect Northflank, Render, and other platforms.
Adding a custom domain to your app means replacing the generic platform URL (like app-12345.northflank.io) with your own domain (like app.example.com). The process has three core steps: add your domain to your hosting platform's dashboard, update DNS records at your registrar, and verify the connection works. Most setups go live within 30 minutes, though DNS propagation can take up to 24 hours in rare cases.
Why Add a Custom Domain?
A custom domain is your first step toward appearing established. Instead of sharing a platform URL that screams "I just deployed this," you share your own domain. This simple shift changes how customers perceive your app.
Branding and trust are the obvious wins. "Visit app.example.com" sounds professional. "Visit app-northflank-staging.io" does not. If you're asking customers to enter credit card information or trust their data to you, they notice the difference. A custom domain signals that you are invested in the service, not running a side project.
Email deliverability is the underrated reason. When you send emails from your app, the sender address (mail@example.com) carries weight. Email providers check the domain reputation. If you are using a shared platform domain, email reputation is pooled: your app's spam-like behavior tanks delivery for everyone else on that platform, and vice versa. Bounces and spam filters are more aggressive with generic domains. Your own domain separates your reputation from everyone else's.
Third, custom domains prevent the perception of lock-in. If your app is forever tied to northflank.com or render.com, users assume switching platforms means losing the custom URL and all associated links. True or false does not matter: the perception exists. A custom domain is yours independent of the platform. This matters when you are selling SaaS, a white-label service, or anything you want to feel autonomous.
What You Need Before You Start
You need three things: a domain name owned by you or managed by you, access to your hosting platform's dashboard, and access to your registrar or DNS provider's dashboard.
A domain name costs between $8 and $15 per year from most registrars (Namecheap, GoDaddy, Route53, Cloudflare). Buy one if you do not have it. If you already own a domain through a registrar, great: you will use the same one.
Access to your hosting platform's dashboard is essential. Whether you are on Render, Heroku, Northflank, Railway, or another platform, you will find a Domains or Custom Domains section. You will need to add your domain there and copy the DNS values the platform gives you.
Access to your registrar's DNS settings is where most people get confused. Your registrar (Namecheap, GoDaddy, Cloudflare, Route53, etc.) manages the actual DNS records for your domain. When you bought the domain, you got access to a dashboard where you can modify these records. If you cannot remember the registrar, check the email confirmation from when you bought the domain, or search for your domain at whois.com: it will tell you who manages it.
One mental model to lock in: DNS is a routing system. When someone types app.example.com into their browser, the browser asks "Where does app.example.com live?" DNS answers with an IP address or another domain name. You tell DNS where your app lives by adding records at your registrar. The platform tells you what values to add. Simple.
CNAME vs A Records: Which One Do You Need?
Most people will use a CNAME record. CNAME points your domain at the platform's address instead of an IP. If you are adding app.example.com as a subdomain, use CNAME. If you are using the root domain (example.com with no prefix), you probably need an A record, though CNAME flattening can work.
CNAME is simpler and more flexible. You tell DNS: "When someone asks for app.example.com, point them to app-platform.heroku.com." The platform manages the IP behind heroku.com, so if the platform's infrastructure changes, your domain keeps working. You do not have to change anything.
A record is a direct IP pointer. "When someone asks for example.com, send them to 1.2.3.4." This only works if the IP never changes. Platforms discourage this because infrastructure updates break your domain. If the platform moves servers or upgrades capacity, your A record now points to a dead IP, and your domain stops working. This is exactly what happened in Opsily's recently published troubleshooting guide: users on Northflank had A records that became stale after infrastructure updates.
CNAME flattening is a middle ground. Some DNS providers (Cloudflare, AWS Route53, others) flatten a CNAME at the root domain level, so you can use CNAME for example.com instead of a subdomain. Check whether your registrar supports this. If you are unsure, email their support.
The rule: subdomain (app.example.com) equals CNAME. Root domain (example.com) equals ask your registrar if they support CNAME flattening: if yes, use CNAME; if no, use A record but accept the risk.
Step 1: Add Your Domain in Your Hosting Platform
Find the Domains or Custom Domains section in your platform's dashboard. On Render, it is in the service settings. On Heroku, it is in the Settings tab. On Northflank, it is under Networking. The location varies, but the concept is identical.
Enter your domain name (e.g., app.example.com) into the field. The platform will generate DNS values for you: either a CNAME target (like app.example.herokuapp.com) or an A record IP (like 1.2.3.4). Some platforms generate both; use the CNAME unless you know you need an A record.
Copy the values the platform gives you. These are the instructions you will follow at your registrar. Write them down or keep the browser tab open. You will need them in the next step.
Do not close the platform dashboard yet. Some platforms show a status icon (like Pending or DNS Not Configured) that updates as you add DNS records on the registrar's side. This real-time feedback is helpful for verification.
Step 2: Update DNS Records at Your Registrar
Log into your registrar's dashboard (Namecheap, GoDaddy, Route53, Cloudflare, etc.). Find the DNS settings or Advanced DNS section. The location depends on your registrar, but it is usually under a Manage DNS, DNS Management, or Advanced tab.
Look for the option to add a new record. You will choose the record type (CNAME or A) and fill in the details the platform gave you.
For a CNAME record, you will enter:
- Name/Host: the subdomain (e.g., app if your full domain is app.example.com)
- Value/Target: what the platform gave you (e.g., app.example.herokuapp.com)
- TTL: leave as default (usually 3600 seconds, or auto)
For an A record, you will enter:
- Name/Host: the root domain (example.com) or subdomain (app)
- Value: the IP address the platform provided
- TTL: leave as default
TTL (Time to Live) controls how long DNS results are cached. A lower TTL means changes propagate faster but increases DNS queries. A higher TTL reduces queries but slows propagation. For setup, default is fine. If you make mistakes and need to fix DNS records fast, you can lower TTL before making changes, but this is an advanced move.
After filling in the values, save the record. Most registrars show a confirmation message. You are done at the registrar's side.
Step 3: Verify It's Working
DNS changes take time to propagate. You will see your new records live everywhere within 30 minutes in most cases, but in some parts of the world it can take up to 24 hours (rare). Start checking immediately: often it is much faster.
Use a DNS checker to see if your records are live. Go to mxtoolbox.com or whatsmydns.net, enter your domain, and check whether the CNAME or A record is showing the value you just added. If it shows the new value immediately, great. If it still shows the old value or nothing, wait 5-10 minutes and check again.
Once DNS propagation looks good, test the domain in your browser. Type app.example.com and see if it loads your app. If it does, you are mostly done.
Check whether SSL/HTTPS is working. Your browser should show a green lock or similar indicator that the connection is secure. Most platforms issue an SSL certificate automatically when you add a domain, but certificate setup sometimes lags behind DNS propagation by a few minutes. If the domain loads but shows an SSL warning, wait a few minutes and refresh.
If you see errors, check your platform's dashboard. The domain status should show Active or Configured within a few minutes. If it shows Error or DNS Not Configured, double-check the DNS values at your registrar against what the platform specified.
Common Mistakes and Troubleshooting
The most common mistake is a typo in the DNS record. You copy the platform's value, add it at the registrar, but misspell it or miss a character. Double-check every value character by character. This accounts for about 40 percent of "it is not working" cases.
TTL confusion causes the second type of failure. If you check DNS immediately after adding the record and it is not showing yet, you hit TTL cache. Your browser or local DNS cache is still serving the old value. Wait 5-10 minutes or clear your browser cache (Ctrl+Shift+Delete in Chrome). If you are on macOS, run sudo dscacheutil -flushcache in terminal.
DNS still showing the old IP is the third culprit. This usually means your registrar is caching old DNS data, or you did not save the new record properly. Log back in and verify the record was actually saved. Some registrars require clicking a save button after adding the record.
SSL certificate delays happen because the platform issues certificates asynchronously. DNS is live, but your browser shows an SSL error because the platform's certificate authority has not validated the domain yet. Wait 5-15 minutes and refresh.
Platform cleared your domain after an infrastructure update is a known issue, especially on Northflank. This happens when infrastructure moves and your A record now points to a dead IP. The solution: if you used CNAME, your domain will auto-recover. If you used A record, update it to the platform's new IP. This is exactly why CNAME is safer.
Making Custom Domains Simple: Why Ship Exists
Setting up a custom domain works, but it exposes you to complexity that should not be your problem. Each platform (Heroku, Render, Northflank, Railway) has slightly different workflows. DNS configuration is universal but registrar dashboards differ. SSL setup is automatic but timing is unreliable. Infrastructure updates can break your domain.
Ship solves this by treating custom domains as a built-in feature, not an add-on. You add your domain in Ship's dashboard, get a single CNAME target, add it at your registrar, and forget about it. SSL is automatic and always valid. Infrastructure updates do not touch your domain. Flat-rate pricing means no surprises from platform-specific costs.
This matters because infrastructure stability is not cheap to build. Northflank has had multiple incidents where platform updates broke customer domains. Vercel and Render have had similar issues. Ship's entire architecture is built around preventing this. You get a dedicated IP for your app and guaranteed domain stability.
If you want the simplest path: add domain, it just works, never breaks. Ship handles this. You can always migrate later. For hobbyist projects or experiments, the complexity of manual DNS setup is fine. For apps you are monetizing or sharing with customers, stability and simplicity compound in value.
Frequently Asked Questions
How long does DNS propagation take?
Most DNS changes are live within 5-30 minutes globally. In rare cases, propagation takes up to 24 hours if some regional DNS servers are slow to update. Use a checker like whatsmydns.net to see global propagation.
Can I use the root domain (example.com) or do I need a subdomain?
You can use the root domain if your registrar supports CNAME flattening. Otherwise, use a subdomain (app.example.com, www.example.com, etc.) and set up CNAME. A records work but are risky because IP changes break your domain.
What if I change platforms: do I lose my custom domain?
No. Your custom domain is registered to you, not to the platform. You can point it to any platform's DNS target. To switch platforms, you change the DNS record at your registrar to point to the new platform instead. The domain stays yours.
Does my custom domain need to be on the same registrar as my hosting platform?
No. Your registrar (where your domain is registered and DNS is managed) is separate from your hosting platform. You can buy a domain from Namecheap and host your app on Render. They do not need to know about each other.
What does TTL mean and should I change it?
TTL (Time to Live) is how long DNS results are cached. Higher TTL (like 3600) means faster queries but slower updates if you change DNS. Lower TTL (like 300) means faster updates but more frequent queries. For initial setup, the default is fine.
Why is my domain showing an SSL error even though DNS is working?
The platform's certificate authority is still validating your domain. Wait 5-15 minutes and refresh. SSL setup is automatic but async. If it persists beyond 30 minutes, contact your platform's support.
Do I need to set up email for my custom domain?
Not immediately. Your app can send emails from any domain. If you want to send from mail@example.com instead of mail@platform.com, you will add an MX record at your registrar later. That is a separate step beyond this guide.
The Bottom Line
Adding a custom domain means replacing your platform URL with your own. Add the domain in your platform's dashboard, copy the DNS values, add them at your registrar, and verify within 30 minutes. Most setups work first try if you avoid typos and wait for DNS to propagate.
The real lesson: custom domains are conceptually simple but infrastructure details (A records breaking, timing issues, platform differences) create unnecessary friction. Ship includes custom domain support with guaranteed stability, making it worth trying free if your app is customer-facing. If you are building on Northflank, Render, or Heroku, you are managing this manually. Ship handles it for you.
Start with this guide, set up your domain, and test it. If you want the setup to just work without monitoring propagation or worrying about infrastructure updates breaking things, try Ship free.