How do I preview emails in development without sending them?
One Shot uses letter_opener in development, so every deliver_later opens the rendered email in a browser tab instead of sending it. No key and no account are needed. That is how you read a sign-in code locally, and it means a seed script cannot accidentally email a real address.
Just run the app
bin/dev
Start a sign-in with any email address. The message opens in a new tab with the six-digit code in it. Copy it, paste it into the verification screen, and you are in. That is the same flow a production user goes through, delivered differently.
Why this is safer than a test inbox
A real SMTP configuration in development means one careless Account.find_each in a console is a
mass email to your customers. With letter_opener there is no transport at all, so the worst case is
a lot of browser tabs.
It also removes a setup step. A new clone runs the auth flow immediately, with no key to request first, which is the same reason billing and bot checking ship with local fakes.
Reading the message without the browser
Jobs run through Solid Queue, so the mail is delivered asynchronously. If a tab does not open, look at the log rather than assuming the mailer is broken:
bin/rails runner 'SignInCodeMailer.code(User.first, "123456").deliver_now'
deliver_now skips the queue and renders immediately, which separates a mailer problem from a job
problem.
Test the HTML and the text version
Every mailer here ships both. The text part is what a lot of clients actually render, and it is the
one nobody looks at. letter_opener shows both, with a toggle. Worth checking once per mailer,
because a text part that renders as one unbroken paragraph is the normal failure.
Moving to real sending
Set RESEND_API_KEY and MAIL_FROM and production delivers for real. Development stays on
letter_opener regardless, which is deliberate: you should not be able to send real mail from your
laptop by setting one variable.
To add a new email, use the add-mailer skill. It writes the mailer, both views and the spec in the
shape the existing ones use.