Module 5 of 10
Domain and real sign-up emails
A video for this module is coming.
Your app already works at a free address like my-app.vercel.app. This module gives it a proper address of your own, and makes sign-up emails real. It is the first step of /shipyard:launch, the skill for going from a free test app to a real product.
What you'll do
You will buy a domain (your own web address), let Shipyard connect it to your app, set up a service that sends your app's emails, and switch sign-ups from "starter" to "verified". You do the buying and the pasting at your registrar (the company you bought the domain from). Claude runs every command.
Prices in this module are as of October 2026. Check them before relying on them.
Why bother
Until now your app is in starter mode. Anyone can sign up with any email address, even one that is not theirs, because nobody checks. That is fine for learning and demos.
For real users you want two things:
- An address that looks trustworthy, such as
recipes.exampleinstead ofmy-app.vercel.app. - A confirmation email at sign-up. The person clicks a link in it, and that proves they own the address. Password-reset emails also start reaching everyone, not only you.
Before you start
- Your app is live (module 2).
- Your Resend key is in your keys file. Resend is the service that sends your app's emails. If you skipped it during setup, Claude will ask you to add it, and you paste it into the keys file yourself, never into the chat. Make the key with "Full access", because it has to create your sending domain.
- You have a card to pay for the domain. You pay at the registrar. Shipyard never pays and never sees your card.
Steps
Claude runs these commands for you inside Claude Code. They are shown so you know what is happening; they do not work if you paste them into a normal terminal.
In Claude Code, inside your app folder, run
/shipyard:launchand choose "Own web address and real sign-up emails". Claude checks that your app is live first.Buy a domain. A domain costs about $10 to $15 a year. Cloudflare Registrar sells at cost and Porkbun is also popular. A short name that matches your app is best.
.comis the safest ending, but others are fine. You buy it yourself.Claude adds the domain to your Vercel project and prints a table of DNS records. DNS records are lines at your registrar that point your name at your app. The command is:
node "${CLAUDE_PLUGIN_ROOT}/scripts/launch-domain.mjs" <appDir> <your-domain>Open your registrar, find the domain, then DNS (or "DNS records"). Paste each line from the table exactly: type, name and value. If your registrar is Cloudflare, set the proxy to "DNS only" (the grey cloud) for the Vercel records.
Claude waits for the domain to work:
node "${CLAUDE_PLUGIN_ROOT}/scripts/launch-domain.mjs" <appDir> <your-domain> --checkIt checks every 15 seconds for up to 10 minutes. DNS can be slower than that. If it times out, try again in an hour. When it passes, it updates your app's public address, your sign-in settings and your profile.
Press one button yourself. Vercel serves
www.<your-domain>as a second copy of your site until you tell it to redirect. In the Vercel dashboard: your project, Settings, Domains, Edit next towww, "Redirect to Another Domain", choose your main address, 308, Save. The--checkcommand keeps failing until this is done, so run it again afterwards.Claude sets up a sending address on a subdomain such as
send.<your-domain>. This keeps email trouble away from your main domain. It creates the domain in Resend and prints a second table of DNS records (SPF, DKIM and a return path: lines that prove the emails really come from you, so they do not land in spam). Paste these at your registrar too:node "${CLAUDE_PLUGIN_ROOT}/scripts/launch-email.mjs" <appDir> --domain send.<your-domain>Claude waits for Resend to say the domain is verified:
node "${CLAUDE_PLUGIN_ROOT}/scripts/launch-email.mjs" <appDir> --checkIt then makes a separate, send-only key for this app and connects Supabase's sign-up emails to Resend. Your main Resend key stays on your computer.
Switch to verified sign-ups:
node "${CLAUDE_PLUGIN_ROOT}/scripts/launch-email.mjs" <appDir> --switch-to-verifiedThis turns on email confirmation. If your app has an email list, people who ticked the box while sign-ups were unconfirmed are left out until they tick it again, because nobody proved those addresses were theirs. Claude will tell you.
Redeploy. The sign-up mode is baked in when the app is built, so the change only shows after a new deploy. Claude runs
deploy.mjsfor you.
What changes for your users
- New people get an email and must click the link before their first sign-in.
- The address they typed is proven to be theirs, so Google sign-in becomes safe to switch on.
- Emails come from
noreply@send.<your-domain>.
Done when
- Your app opens on your own address, and
wwwredirects to it. - You signed up with a second email address of your own, the confirmation email arrived (check spam too), and clicking the link signed you in.
- Trying to sign in before confirming says "email not confirmed" and offers to send it again.
- The Health page (
/admin/health, for admins only) shows sign-up mode and the Resend domain as green.
If something goes wrong
- The registrar says the domain is not found, or the checks keep failing. Look for typos in the pasted records, then wait. DNS can take up to an hour or more.
- Resend stays "pending". A record is missing, or your registrar added your domain to the end of the name by itself, so it appears twice. Paste the name without the domain part.
- Vercel says the domain belongs to another account. Remove it from the other account first, then run the command again.
- Confirmation emails land in spam. Wait a day, mark one as "not spam", and check that the SPF and DKIM lines show as verified in Resend.
- The command says it removed an older Resend key. That happens on a new computer or when the sending domain changed. Redeploy straight away, because the live app uses the old key until you do.