Skip to content

feat(landing): per-link branding overrides#209

Merged
saltyskip merged 1 commit into
mainfrom
feat/landing-per-link-override
Jun 17, 2026
Merged

feat(landing): per-link branding overrides#209
saltyskip merged 1 commit into
mainfrom
feat/landing-per-link-override

Conversation

@saltyskip

Copy link
Copy Markdown
Owner

Why

Branding (LandingTheme) is tenant-wide — you couldn't, e.g., hide the agent panel on one acquisition link but keep it on others. This adds a per-link override that merges over the tenant theme at render time.

How

  • LandingThemeOverride — an all-optional mirror of LandingTheme; Some replaces the tenant value, None inherits. LandingTheme::merged_with(override) does the merge.
  • Link.landing_theme (DB) + plumbed through CreateLinkInput (+builder), CreateLinkRequest, LinkDetail, and UpdateLinkRequest (absent = unchanged, null = clear, object = replace).
  • Resolve merges the link override over the tenant theme: tenant default → tenant theme → link override.
  • Validation via LinkError::InvalidLandingTheme (reuses core::validation); OpenAPI schema registered.
  • MCP: the links.create tool takes CreateLinkRequest, which now carries landing_theme, so it's available over MCP automatically.

Usage

POST /v1/links
{ "custom_id": "reddit", "ios_store_url": "...",
  "landing_theme": { "show_agent_panel": false, "hide_cta_on_desktop": true, "cta_label": "Open App" } }

Tests

Per-link override hides the agent panel on one link while a control link (no override) keeps it. fmt + clippy -D warnings clean.

🤖 Generated with Claude Code

Adds an optional per-link override that merges over the tenant's LandingTheme
at render time — every field optional, Some replaces, None inherits. Lets a
single link tweak branding (e.g. hide the agent panel or change the CTA on an
acquisition link) without a separate tenant.

- LandingThemeOverride (all-optional mirror of LandingTheme) + LandingTheme::merged_with.
- Link.landing_theme; CreateLinkInput (+builder), CreateLinkRequest, LinkDetail;
  UpdateLinkRequest with the absent/null/value pattern (null clears).
- Resolve path merges the link override over the tenant theme.
- Validation: LinkError::InvalidLandingTheme via validate_landing_theme_override
  (reuses core::validation). OpenAPI schema registered. Shared over MCP (the
  create tool takes CreateLinkRequest, which now carries landing_theme).

Test: per-link override hides the agent panel on one link while a control link
(no override) keeps it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
rift Ready Ready Preview, Comment Jun 17, 2026 3:33pm

Request Review

@saltyskip
saltyskip merged commit c13727b into main Jun 17, 2026
6 checks passed
@saltyskip
saltyskip deleted the feat/landing-per-link-override branch June 17, 2026 16:02
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