Overview
Portless automatically routes wildcard subdomains to their parent route. Once you register an app (e.g.,myapp), any subdomain of that app routes to it automatically without extra configuration.
This is especially useful for:
- Multi-tenant applications
- Dynamic preview environments
- Per-user subdomains
- Testing subdomain-based features locally
How It Works
When portless receives a request, it:- Checks for exact hostname match - If
myapp.localhostis registered, it matches first - Falls back to wildcard matching - If no exact match, checks if the hostname ends with
.+ a registered route - Routes to the parent -
tenant1.myapp.localhostroutes to the app registered atmyapp.localhost
You only register the base name once. All subdomains work automatically.
Quick Example
Host header and can route internally.
Multi-Tenant Applications
Setup
1
Register your app once
2
Access different tenants
Each tenant gets a unique subdomain:
3
Handle routing in your app
Your app reads the
Host header to determine the tenant:Express Example
Next.js Example
middleware.ts
Dynamic Preview Environments
Wildcard routing is perfect for branch-based or PR-based preview URLs:Per-User Subdomains
Build GitHub-style user pages or per-user dashboards:Real-World Examples
SaaS Application with Tenant Isolation
Localization Testing
Microservices with Per-Service Subdomains
Exact matches take precedence over wildcards. If you register both
myapp and api.myapp, requests to api.myapp.localhost route to the explicit api.myapp registration, not the wildcard for myapp.How Wildcard Matching Works
Matching Algorithm
Priority Order
- Exact hostname match -
myapp.localhostmatchesmyappregistration - Longest wildcard match -
api.myapp.localhostmatchesapi.myappbeforemyapp - 404 - No match found
Headers and Request Context
X-Forwarded-* Headers
Portless adds standard forwarding headers to every request:Host Header
TheHost header is not rewritten - your app receives the full subdomain:
Combining with Static Routes
You can mix wildcard routing with static routes for external services:Limitations
Safari and .localhost DNS
Safari relies on system DNS resolution, which may not auto-resolve.localhost subdomains. If you see DNS errors:
/etc/hosts. See Safari DNS for details.
HTTPS and Wildcards
When using HTTPS, portless generates per-hostname certificates on-demand via SNI (Server Name Indication). The first request to a new subdomain triggers certificate generation, which takes ~100ms. Subsequent requests to the same subdomain use the cached certificate. See HTTPS & HTTP/2 for details.No Deep Wildcard Nesting
Wildcard matching is simple suffix-based. If you registermyapp, these work:
sub.myapp.localhost✓deep.sub.myapp.localhost✓any.depth.works.myapp.localhost✓
myapp.