Skip to content

fix: support multi-segment custom TLDs#277

Open
KingPsychopath wants to merge 1 commit intovercel-labs:mainfrom
KingPsychopath:fix/multi-segment-tld
Open

fix: support multi-segment custom TLDs#277
KingPsychopath wants to merge 1 commit intovercel-labs:mainfrom
KingPsychopath:fix/multi-segment-tld

Conversation

@KingPsychopath
Copy link
Copy Markdown

@KingPsychopath KingPsychopath commented May 2, 2026

Summary

Refs #260.

Allow custom TLDs to be multi-segment DNS suffixes such as local.example.dev or dev.example.com.

This means users can now run:

portless --tld local.example.dev run --name myapp vite dev
# https://myapp.local.example.dev

The change also keeps the app name clean. The previous workaround was to use a single final label as PORTLESS_TLD and put the rest of the domain into the app name, for example PORTLESS_TLD=dev with --name myapp.local.example. That can produce a usable URL, but it treats domain structure as app naming. This PR makes the configured TLD itself multi-segment.

Context

Related issues and discussions:

What Changed

  • Allow validateTld to accept dot-separated DNS labels.
  • Enforce DNS-safe label rules, 63-character label limits, and 253-character total length.
  • Accept --tld in run mode and named app mode, including leading placement before run or the app name.
  • Preserve multi-segment PORTLESS_TLD through proxy start config.
  • Add regression coverage for validation, env handling, proxy start args, CLI parsing, hostname construction, and SNI certificate SAN generation.
  • Update README, CLI help, skills/portless/SKILL.md, and skills/oauth/SKILL.md.

Certificate Behavior

#260 mentions a possible single wildcard cert for *.dev.example.com. This PR does not add a new wildcard-cert mode.

Instead, it keeps the existing SNI certificate strategy and verifies that multi-segment TLD app hosts get a valid per-host certificate. For example, myapp.local.example.dev receives SANs like:

DNS:myapp.local.example.dev
DNS:*.local.example.dev

That keeps the fix focused while covering browser and curl hostname validation for the actual app URL.

Hosts Resolution

Existing per-host /etc/hosts sync continues to work unchanged: each registered app writes its full <app>.<tld> entry. Users with PORTLESS_SYNC_HOSTS=0 can still use DNS they control or explicit resolver overrides. The manual smoke test used curl --resolve to verify the proxy path without mutating the hosts file.

Validation

  • pnpm --filter portless type-check
  • pnpm test
  • Manual smoke test with curl --cacert ... --resolve myapp.local.example.dev:<port>:127.0.0.1 https://myapp.local.example.dev:<port>/check

Trimmed smoke-test output:

{"host":"127.0.0.1:4576","url":"/check","proto":"https","port":"4576","urlEnv":"https://myapp.local.example.dev:13556"}

The manual smoke test verified route registration, PORTLESS_URL, HTTPS proxying, and the generated certificate SAN for a multi-segment TLD.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 2, 2026

@KingPsychopath is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

@KingPsychopath KingPsychopath force-pushed the fix/multi-segment-tld branch from 3ab16a6 to 1a9b34b Compare May 2, 2026 20:17
@KingPsychopath KingPsychopath marked this pull request as ready for review May 2, 2026 20:24
@KingPsychopath
Copy link
Copy Markdown
Author

Marked ready for review.

This keeps the scope focused on multi-segment --tld / PORTLESS_TLD support, with the existing SNI cert path handling valid per-host SANs. I left the single-wildcard-cert idea from #260 as a possible follow-up because it changes certificate strategy rather than being required for correctness.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant