to select ↑↓ to navigate
Buzz

Buzz

Open in ChatGPT
Ask ChatGPT about this page
Open in Claude
Ask Claude about this page

Short URLs (/b) & Back-Compat Redirects

Buzz public links got shorter. The dashboard now lives under /b instead of /dashboard, registration and custom event-form links are much shorter, and every old link keeps working through automatic redirects.

What changed for hosts

The links you share with attendees and sponsors are now shorter and cleaner:

Purpose Old link New link
Registration page /dashboard/book-tickets/<event> /b/<event>/register
Custom event form /dashboard/events/<event>/forms/<form> /b/<event>/<form>
Event proposal /dashboard/event-proposal /b/event-proposal
Attendee account / tickets /dashboard/account/tickets /b/account/tickets
Check-in scanner /dashboard/check-in/<event> /b/check-in/<event>

You don't need to update anything you've already shared — old /dashboard/* links redirect to the new /b/* links automatically. The Copy link and View Registration Page buttons on the Buzz Event form already produce the new short links.

One thing to know: a few words are now reserved and can't be used as an event route (because they're top-level app paths). If you try to save an event whose route is one of these, Buzz will ask you to pick another: account, bookings, tickets, register-interest, check-in, book-tickets, event-proposal, events. Likewise, a custom form route can't be register (that's the event's registration page).

How it works (for developers)

A request can arrive either as a new /b/* link or as a legacy /dashboard/* link. Legacy links are 301-redirected to the new scheme at the web layer; everything under /b/* is then served by the dashboard SPA, whose Vue router resolves the final page. Registration lives at /b/<event>/register, matched before the /b/<event>/<form> custom-form catch-all so it always wins. The reserved-route guard on Buzz Event prevents an event slug from shadowing a real dashboard route, which is what makes the two-segment URLs safe.

flowchart TD
    visitor(["Incoming request"]) --> legacy{"Legacy /dashboard/* link?"}
    legacy -->|yes| redirect["301 redirect to /b/*<br/>(website_redirects, hooks.py)"]
    legacy -->|no| routerule["/b/* served by dashboard SPA<br/>(website_route_rules)"]
    redirect --> routerule
    routerule --> spa["Vue router, base /b<br/>static routes matched first"]
    spa --> inapp{"Old in-app path?"}
    inapp -->|yes| inappredirect["Router redirect to<br/>new route name"]
    inappredirect -. re-resolve .-> spa
    inapp -->|no| reg{"/&lt;event&gt;/register ?"}
    reg -->|yes| booking["Registration page<br/>(matched first)"]
    reg -->|no| catchall["Catch-all (declared last)<br/>/&lt;event&gt;/&lt;form&gt; custom form"]
    guard[("Reserved-routes guard<br/>(buzz_event.py) blocks<br/>shadowing event slugs")] -. guards .-> catchall
    booking --> page(["Page renders"])
    catchall --> page

URL scheme

The SPA base path moved from /dashboard to /b (dashboard/src/router.tscreateWebHistory("/b")), and buzz/hooks.py serves the SPA from the new base:

website_route_rules = [
    {"from_route": "/b/<path:app_path>", "to_route": "dashboard"},
]
Area Old path New path
SPA base /dashboard /b
Booking /dashboard/book-tickets/:event /b/:event/register
Custom form /dashboard/events/:event/forms/:form /b/:event/:form
Event proposal (global) /dashboard/event-proposal /b/event-proposal (unchanged path)
Payment redirects /dashboard/...?success=true /b/...?success=true

Back-compat redirects

Old links keep working through two layers.

1. Server-side 301s (buzz/hooks.py) — ordered specific → catch-all, first match wins:

website_redirects = [
    {"source": r"/dashboard/events/([^/]+)/forms/([^/]+)", "target": r"/b/\1/\2"},
    {"source": r"/dashboard/book-tickets/(.+)", "target": r"/b/\1/register"},
    {"source": r"/dashboard/(.*)", "target": r"/b/\1"},
]

2. In-app Vue router redirects (dashboard/src/router.ts) — so deep links and client-side navigations to the old paths still resolve:

{ path: "/book-tickets/:eventRoute", redirect: (to) => ({ name: "event-booking", params: to.params }) },
{ path: "/events/:eventRoute/forms/:formRoute", redirect: (to) => ({ name: "custom-form", params: to.params }) },

Reserved routes

Because event URLs are now /b/<event>/... (event first), an event route must not collide with a top-level dashboard segment, or the event would shadow a real route. buzz/events/doctype/buzz_event/buzz_event.py enforces this on validate:

RESERVED_EVENT_ROUTES = {
    "account", "bookings", "tickets", "register-interest",
    "check-in", "book-tickets", "event-proposal", "events",
}

RESERVED_FORM_ROUTES = {
    "register",
}

If an event's route resolves to a reserved event word, save fails with a clear message. A custom form route can't be register, since /b/<event>/register is the registration page — it's matched before the /b/<event>/<form> catch-all (declared last in the Vue router), so registration always wins and a form named register would otherwise be unreachable.

Files touched

  • buzz/hooks.py — new /b route rule + website_redirects
  • dashboard/src/router.ts — base /b, new route names, in-app back-compat redirects, catch-all declared last
  • buzz/events/doctype/buzz_event/buzz_event.pyRESERVED_EVENT_ROUTES + RESERVED_FORM_ROUTES guards
  • buzz/events/doctype/buzz_event/buzz_event.js — Copy link / web link buttons emit /b/*
  • buzz/api/__init__.py, buzz/api/auth.py, buzz/payments.py callers, buzz/buzz_marketing/.../buzz_campaign.py, buzz/proposals/.../sponsorship_enquiry.py, buzz/ticketing/.../event_ticket.py — server-generated links/redirects updated to /b/*
  • e2e/ page objects and specs — updated to the new paths
Last updated 1 month ago
Was this helpful?
Thanks!