Skip to content

feat: support wildcard domains on Vercel - #8

Open
charliedevelops wants to merge 4 commits into
opencoredev:mainfrom
charliedevelops:vercel-wildcard-domains
Open

feat: support wildcard domains on Vercel#8
charliedevelops wants to merge 4 commits into
opencoredev:mainfrom
charliedevelops:vercel-wildcard-domains

Conversation

@charliedevelops

@charliedevelops charliedevelops commented Aug 15, 2026

Copy link
Copy Markdown

The Vercel adapter declares wildcardDomains: false. createDomainClient passes that flag to normalizeHostname as allowWildcard, so add("*.example.com") throws INVALID_HOSTNAME, and createSubdomainClient's provisionWildcard() throws UNSUPPORTED_OPERATION. Both fail before a request reaches Vercel.

Vercel supports wildcard project domains. POST /v10/projects/:id/domains accepts *.example.com as name, and get, verify, list, remove and the domain-configuration lookup address it identically. No adapter code below the capability flag treats a wildcard differently.

Why no adapter code

The other two adapters that declare wildcardDomains: true both branch on wildcards, so it is worth saying why this one does not. Render's API returns no DNS records, so its adapter synthesizes them from known conventions and a wildcard needs an extra _acme-challenge CNAME it has to author itself; bunny.net does the same for DNS validation.

The Vercel adapter reads its records instead — recommendedIPv4 and recommendedCNAME from /v6/domains/:d/config, and the challenges from the project-domain response — so whatever a wildcard requires arrives through fields it already maps. The generic wildcard handling in core/hostname.ts and core/subdomains.ts was already there; the capability flag was the only gate.

One gap this leaves: the adapter does not read acceptedChallenges. If Vercel returns a wildcard certificate challenge only in that field rather than in verification[], it would not reach the caller. Every wildcard checked here was either already serving or unowned, so that state was not observable from outside.

Changes

  • wildcardDomains: true on the Vercel adapter.
  • Wildcard lifecycle test over add, get, refresh, verify, list and remove, asserting normalized hostnames and request paths. Paths keep a literal *, since encodeURIComponent does not escape it.
  • Capability matrix and Vercel provider docs updated.

provisionWildcard() is left to its existing coverage in test/core/subdomains.test.ts, which already exercises both capability states against a provider.

Verified against the live API

Rather than inferred from documentation:

  • A wildcard attaches, hostname round-trips as *.example.com rather than folding to its apex, and remove is clean.
  • configuredBy reports A or CNAME depending on which record shape is used. Both work, and Vercel's own nameservers are not required — the wildcards checked are served from third-party DNS.
  • misconfigured is evaluated against the project named in the request. A wildcard whose DNS is correct but which is attached to a different project reports misconfigured: true with an empty acceptedChallenges. That is documented, since it is easy to read as a DNS fault.

An earlier revision of this PR claimed the apex must be verified on the account and that a DNS-01 ownership record must persist for renewal. Neither survived checking, and both were removed in 7e154dd.

Testing

  • packages/sdk: bun test (68 pass), check-types, lint, build
  • apps/fumadocs: check-types, lint, build
  • Root: test, typecheck, lint, build

Copilot AI lite review requested due to automatic review settings August 15, 2026 22:49
@vercel

vercel Bot commented Aug 15, 2026

Copy link
Copy Markdown

@charliedevelops is attempting to deploy a commit to the OpenCore Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enables wildcard hostname support (*.example.com) for the Vercel provider by advertising the capability, adding a regression test to ensure the wildcard is sent intact to Vercel, and updating the provider documentation/capability matrix to reflect the operational requirements for wildcard certificates.

Changes:

  • Enable wildcardDomains: true in the Vercel adapter capabilities (with an operator-focused caveat comment).
  • Add a provider test asserting a wildcard hostname is POSTed as *.customer.com (not folded to the apex).
  • Update Vercel provider docs and the provider capability matrix to reflect wildcard support and requirements.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
packages/sdk/test/providers/vercel.test.ts Adds a test to ensure wildcard hostnames are attached intact when calling the Vercel adapter.
packages/sdk/src/providers/vercel/index.ts Flips Vercel capability flag to support wildcard domains and documents operational caveats.
apps/fumadocs/content/docs/providers/vercel.mdx Updates Vercel provider docs to describe wildcard support and certificate/verification requirements.
apps/fumadocs/content/docs/providers/index.mdx Updates the capability matrix and provider comparison text to include Vercel wildcard support.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +96 to +99
if (url.pathname === "/v10/projects/prj_123/domains" && method === "POST")
return json(wildcard);
if (url.pathname === "/v6/domains/*.customer.com/config") return json(configuration);
return json({ error: { message: `Unhandled ${method} ${url.pathname}` } }, 500);
@greptile-apps

greptile-apps Bot commented Aug 15, 2026

Copy link
Copy Markdown

Greptile Summary

This change enables Vercel wildcard-domain support, adds full wildcard lifecycle coverage, and updates the provider documentation to describe the supported DNS behavior.

Confidence Score: 5/5

No blocking failure remains.

Wildcard domain operations completed successfully through the Vercel adapter, with normalized hostnames and expected provider request paths.

T-Rex T-Rex Logs

What T-Rex did

  • Ran the wildcard lifecycle contract harness against the parent revision; the parent rejected *.CUSTOMER.COM. with INVALID_HOSTNAME before issuing a request.
  • After applying the hostname normalization change, the harness completed add, configuration lookup, get, refresh, verify, list, and remove operations using mocked Vercel responses, all returning HTTP 200 OK.
  • The recorded paths included the literal wildcard hostname for domain and configuration endpoints, confirming that the complete lifecycle uses the expected Vercel request contract.
  • Executed the PR validation harness command and reviewed both before and after captures; it records methods, exact URLs, status codes, and normalization results, including a transition from pre-change INVALID_HOSTNAME to post-change hostname normalization and HTTP 200 OK responses.
  • No repository source files were modified; only required uploaded proof artifacts were created under the proof artifacts area.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (3): Last reviewed commit: "docs: name every adapter that exposes wi..." | Re-trigger Greptile

Comment thread packages/sdk/test/providers/vercel.test.ts Outdated
@charliedevelops
charliedevelops marked this pull request as draft August 15, 2026 22:55
The adapter declared `wildcardDomains: false`, so `createDomainClient` rejected
`*.example.com` in `normalizeHostname` and `provisionWildcard()` refused with
`UNSUPPORTED_OPERATION` — Vercel never saw the request.

Vercel accepts a wildcard project domain: `POST /v10/projects/:id/domains` takes
`*.example.com` as its `name`, and `get`, `verify`, `remove` and the config
lookup all address it the same way. Verified against the live API: the hostname
round-trips intact and removal is clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@charliedevelops
charliedevelops force-pushed the vercel-wildcard-domains branch from 17b1522 to abfa79f Compare August 15, 2026 23:01
The capability advertises wildcard support for every operation, but only `add`
was exercised. A regression in wildcard URL construction or response
normalization for `get`, `refresh`, `verify`, `list` or `remove` would have
passed the suite.

Covers all six, asserting the normalized hostname stays `*.customer.com` and the
request paths carry the wildcard literally — `encodeURIComponent` leaves `*`
alone, so `/v9/projects/:id/domains/*.customer.com/verify` is the real path and
an encoding change would silently break it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@charliedevelops charliedevelops changed the title feat(vercel): support wildcard hostnames feat: support wildcard domains on Vercel Aug 15, 2026
The first draft claimed the apex must be verified on the account and that a
DNS-01 ownership record has to stay in place for renewal. Neither held up
against the live API: attaching a wildcard for a domain nobody owns returns
`verified: true` immediately, and a wildcard serving traffic today does so from
a third-party DNS provider with no `_acme-challenge` record anywhere in the
zone.

Replaces both with what was observed. Adds the `misconfigured` semantics, which
are easy to misread: the field is evaluated against the project named in the
request, so a wildcard attached to a different project reports
`misconfigured: true` with an empty `acceptedChallenges` even though its DNS is
correct.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@charliedevelops
charliedevelops marked this pull request as ready for review August 16, 2026 04:50
The managed-subdomains guide said Render was the only one. bunny.net has
declared the capability since 0.2.0, and Vercel does as of this branch, so the
page a reader lands on while building exactly this was pointing them away from
two of the three adapters that support it.
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.

2 participants