Skip to main content

Generated Short Links

Status

Current recommendation and first implementation for #92.

Locked Decision

Generated short links are durable pointer records, not vanity slugs.

Canonical public routes stay unchanged:

  • profiles use /p/<slug> for people and /c/<slug> for communities
  • worlds use /w/<slug>
  • events use /e/<slug>

Generated short links use /l/<code> and redirect to the current canonical route for the target. If a target slug changes later, the short link remains stable because it stores the target id, not the slug.

shortLinks stores:

  • immutable generated code
  • targetType: profile, world, or event
  • exactly one target id field for the selected target type
  • createdAt

The first generated code format is lowercase alphanumeric, 5 to 12 characters, with a 7-character default. The generator uses an ambiguity-reduced alphabet, while validation accepts ordinary lowercase alphanumeric codes so old generated codes remain easy to preserve if the alphabet changes.

Reserved codes such as admin, api, health, privacy, qr, search, and other product route words are rejected. Code reservation retries when a generated candidate is reserved or already taken.

Public Redirect Behavior

/l/<code> resolves through Convex and returns 404 instead of redirecting when:

  • the code is invalid, reserved, absent, or not currently reserved
  • the target row no longer exists
  • the target profile is not publicly readable
  • the target profile is opted out or suppressed
  • the target world or event is not published
  • the event no longer has a public slug

The resolver returns only the target type and canonical path. Public short-link reads do not expose source attribution, private event operation fields, media control internals, or moderation notes.

Backend configuration or read failures are not treated as missing short links. The public route should surface a server error for those cases instead of turning an unavailable resolver into a target-level 404.

Creation Contract

Profile community submissions and community event creation now reserve a short link in the same Convex mutation that creates the target row. The mutation return payload includes shortLinkCode and shortLinkPath as additive fields.

World records do not yet have a public write mutation. The backend exposes shortLinks.ensureForWorld for the future world creation flow, and that flow should call it in the same mutation that creates a world row.

Manual shortLinks.ensureForProfile, shortLinks.ensureForWorld, and shortLinks.ensureForEvent calls require a signed-in actor with authority over the target:

  • profile short links require the profile owner or community profile authority
  • world short links require authority over one of the world creator-attribution profiles
  • event short links require the event submitter or manage_events authority on the event community

Calling an ensure mutation for a target that already has a short link returns the existing code without changing it. There is no update mutation for a code.

Out Of Scope

  • vanity or custom short links
  • link analytics
  • QR codes
  • expiring links
  • custom domains
  • broad slug refactors
  • changing canonical route patterns