AUTHENTICATION & FRAMEWORKS
Next.js Local HTTPS for Secure and SameSite Cookies in Development
Testing Auth.js (NextAuth), Supabase, Clerk, or custom OAuth providers locally? Modern browser security policies quietly drop authentication session cookies unless your local dev server runs on trusted HTTPS.
The Problem: Missing cookies on localhost
When redirecting back from an identity provider (Google, GitHub, Apple OAuth) to http://localhost:3000/api/auth/callback, browsers enforce strict cookie storage rules:
Securecookies are discarded over plain HTTP.SameSite=Nonecookies are completely rejected unless accompanied by theSecureattribute.- Third-party OAuth redirects originating from an external HTTPS domain into an HTTP callback are treated as cross-site requests.
- WebAuthn / Passkeys APIs refuse to function in insecure non-localhost contexts.
The CLI workaround: Custom Next.js HTTPS server
Next.js offers an experimental --experimental-https flag, or you can write a custom server.js:
// server.js
const { createServer } = require('https')
const { parse } = require('url')
const next = require('next')
const fs = require('fs')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
const httpsOptions = {
key: fs.readFileSync('./certs/localhost.key'),
cert: fs.readFileSync('./certs/localhost.crt'),
}
app.prepare().then(() => {
createServer(httpsOptions, async (req, res) => {
const parsedUrl = parse(req.url, true)
await handle(req, res, parsedUrl)
}).listen(3000, (err) => {
if (err) throw err
console.log('> Ready on https://myapp.test:3000')
})
})
Why custom servers add maintenance drag
Custom Next.js servers disable Next.js automatic performance optimizations, prevent Turbopack integration in some setups, and complicate deployment pipelines where production runs in Docker or Vercel.
The cleaner solution: CertMon
Keep your Next.js application running standard next dev on port 3000 with Turbopack enabled. Point CertMon to port 3000 with the domain https://myapp.test.
CertMon handles the trusted certificate and terminates TLS on standard port 443. All OAuth callbacks, Secure session cookies, and WebAuthn credentials work seamlessly across development and production.