A single search box works for one traveler on one round trip and fails almost everywhere else. The moment a trip adds a second city, a second traveler, or a flexible date, the number of valid states multiplies faster than a form can hold, so the interface has to shift from "fill in fields" to "progressively disclose a plan." Designing for that shift, not around it, is the actual job.

Quick answer: Multi-city itinerary UX breaks down because legs, travelers, date flexibility, and transport mode combine multiplicatively, not additively. The fix is progressive disclosure (reveal complexity only when a traveler asks for it), a saved-trip state that survives interruption, and defaults tuned so the 80% simple case stays fast without capping what the 20% complex case can do.

Why the Simple Search Box Breaks on Real Trips

A round-trip search box works because it hides exactly two decisions: where and when. Real trips carry four independent dimensions — legs, travelers, date flexibility, and mode — and each one multiplies the form's possible states rather than adding to them.

Consider what "one search" actually means once you unpack it. A single round trip is really: origin, destination, depart date, return date, one traveler type. Add a second city and you're no longer editing two fields, you're inserting a new record with its own origin/destination/date triplet that has to reconcile against the leg before and after it. This is why teams that started with a "clone the row" pattern for multi-city search usually end up rebuilding it as a list-management problem instead — closer to a task list than a form.

The math is the tell. With n legs, t traveler types, a flexible-date window of ±d days, and m transport modes under consideration, the naive search-result space grows on the order of n × t × d × m — and if the flexible window applies independently per leg, it's closer to d^n. A three-city trip with a three-day flex window per leg isn't 3x more complex than a single flight search; it's closer to 27x, before travelers are even added.

The Four Axes That Actually Explode Complexity

Most multi-city UX failures trace back to conflating these axes into one flow instead of designing each as its own layer:

  1. Legs — the number of origin-destination-date segments in the trip, each with its own availability and pricing.
  2. Travelers — not just a headcount, but different traveler types (adults, children, infants, loyalty tiers) that can each need different documents or seat rules per leg.
  3. Date flexibility — a hard date, a ±3-day window, or "whenever it's cheapest," and whether that flexibility is set once for the whole trip or per leg.
  4. Mode — flight, rail, car, or a mix, where a "leg" might not even be the same transport type as the leg before it.
AxisSimple caseComplex caseUX risk if collapsed into one form
Legs1 (A→B)3+ with open jaws (A→B→C→A)Users can't express a city they're "passing through"
Travelers1 adultMixed party across legs (some join later)Traveler assignment gets silently lost per leg
Date flexibilityFixed date±N days or "cheapest month" per legFlex applies globally when the user meant one leg
ModeFlight onlyFlight + rail + car, mode changes per legBooking flow assumes one inventory system throughout

Each row in that table is a place where a generic booking form quietly picks the simple answer for the user, and the user has no way to override it. That's the actual failure mode: not that the interface looks broken, but that it looks fine while silently constraining the trip the traveler is trying to build. This is the same anxiety pattern covered in designing against travel booking funnel anxiety — uncertainty about whether the system understood the request correctly, not a missing feature, is what erodes trust mid-flow.

Progressive Disclosure Is the Only Way Out

Progressive disclosure means showing the single-leg, single-traveler, fixed-date form by default, and revealing each additional axis (a second leg, flexible dates, mixed travelers) only when the user takes an explicit action that signals they need it. It keeps the 80% case fast without hard-capping what the 20% case can build.

Jakob Nielsen's original framing of progressive disclosure — defer advanced or rarely-used features to a secondary screen, keep the primary screen focused on common tasks — was written for desktop software, but it maps almost exactly onto multi-city search. The mistake teams make is disclosing complexity by adding fields rather than by adding steps. A field that appears conditionally on the same screen still competes for scan time with everything already there; a new screen that appears only on request doesn't.

The Wireframe Progression, Leg by Leg

A lo-fi wireframe sequence makes the disclosure boundaries concrete. Sketching these as separate screens, not states of one screen, is what surfaces where the interface actually needs to branch:

  1. Screen 1 — single leg. Origin, destination, one date field, one traveler count. This is the entire interface for the majority of searches and should never visually imply more is coming.
  2. Screen 2 — "+ Add another city" tapped. A second leg row appears below the first, pre-filled so the new leg's origin defaults to the prior leg's destination. This is the single highest-leverage default in the whole flow.
  3. Screen 3 — three-plus legs, reorderable. Legs become a draggable list, each row collapsed to a one-line summary (city pair + date) with an expand affordance, because a full form per leg no longer fits a scannable screen.
  4. Screen 4 — flexible dates requested. Tapping "flexible" on a leg swaps that leg's single date field for a small calendar-strip or ±3/±7 day toggle, scoped to that leg only, not the whole trip.
  5. Screen 5 — mixed travelers or mode. A per-leg traveler override and a per-leg mode selector appear only after the user has already committed to multi-leg complexity — never on screen 1.

Each screen in that sequence is a disclosure boundary: crossing it is optional, and not crossing it costs the user nothing. That's the test for whether disclosure is designed correctly — ask whether a user who never taps "add another city" ever sees a UI cost for the feature existing at all.

Defaults That Keep the Common Case Simple

Progressive disclosure only works if what gets revealed is pre-populated sensibly, not handed to the user as a blank form. The defaults that matter most:

  • Next leg's origin defaults to the prior leg's destination — the single biggest reduction in required taps for a multi-city trip.
  • New legs inherit the trip's traveler count unless the user has already indicated a mixed party.
  • Date flexibility defaults to "exact" per leg, because most legs in a multi-city trip are anchored to something (a meeting, a connection) even when one leg is genuinely flexible.
  • Mode defaults to the mode of the previous leg, since mixed-mode trips are the exception, not the rule, even though the interface must support them.

A defaulting rule that saves one tap on the 80% case is worth more than a feature that unlocks the 20% case — but only if the 20% case is still reachable, not designed away.

Saved-Trip State: The Feature That Makes Complexity Survivable

A multi-city trip is rarely built in one sitting, so the interface needs a durable, resumable trip object — not just form state — that survives a closed tab, a comparison to another site, or a traveler who wants to change one leg without re-entering the other four. Without this, every complex trip effectively resets to zero on any interruption.

The underlying problem is that a three-leg, two-traveler, mixed-mode trip is a meaningful amount of user-entered intent, and losing it isn't a minor annoyance — it's the moment users abandon the flow entirely and go back to booking each leg separately on different sites. Treat the itinerary as a first-class object with its own ID, not a session variable, from the first leg onward.

What Saved-Trip State Actually Needs to Hold

State elementWhy it must persist independentlyFailure if it doesn't
Per-leg locked selectionsUser has already chosen a flight for leg 1 while still shopping leg 2Re-searching leg 2 clears leg 1's choice
Traveler assignments per legNot every traveler is on every leg (joining/leaving trips)Traveler count desyncs across legs silently
Flexible-date search parametersUser may return days later to re-check a flexible legFlexibility setting reverts to a fixed date
Price/availability snapshot per legMulti-leg pricing can be interdependent (through-fares)Total price shown doesn't match final checkout
Trip-level metadata (name, dates, party)Needed to resume, share, or hand off the itineraryUser re-describes the trip from scratch every visit

The pricing snapshot row deserves particular care: many multi-city itineraries are priced as a bundle rather than as independent legs, so a saved-trip object that treats each leg as pricing-independent will show a subtotal that doesn't reconcile at checkout — a trust break that's expensive to recover from this late in the funnel.

This is also where the difference between helpful personalization and something that feels invasive shows up. A saved-trip object that quietly infers a traveler's home airport or preferred cabin from past trips is useful; one that surfaces it without explanation reads as surveillance rather than assistance — the distinction covered in AI concierge personalization versus surveillance applies just as much to itinerary defaults as to recommendations.

Designing the 80% Simple Without Capping the 20% Complex

The governing principle is that the default path should be indistinguishable in effort from a single round-trip search, while the same underlying model supports arbitrary legs, mixed travelers, and mixed modes without a rebuild. Get this wrong in either direction and you either scare away simple bookers or hard-block complex ones.

Two failure modes sit on either side of the target, and most teams find one only after shipping the other:

  • Over-simplified: the form hard-codes "up to 3 legs" or a single traveler type across the whole trip, so a genuinely complex trip (a business traveler adding a personal leg, a family where kids join for one segment) simply can't be built and the user leaves for a travel agent or a spreadsheet.
  • Over-exposed: every field for every axis is visible from screen one — leg count, per-leg flexibility, per-leg traveler mix, per-leg mode — so even a simple one-way search looks like tax software.

The IBM/Nielsen Norman Group body of usability research on progressive disclosure consistently finds that hiding advanced options behind a clear, low-cost affordance ("+ Add another city") reduces perceived complexity without reducing actual capability — the option cost is what changes, not the ceiling.

A Practical Test for the Boundary

Ask three questions of any multi-city flow before it ships, mapped straight to Jobs to Be Done thinking about what the traveler is actually hiring the product to do:

  1. Can a one-leg, one-traveler user complete a search in the same number of taps as today's simple form? If not, disclosure has leaked into the default path.
  2. Can a five-leg, mixed-traveler, mixed-mode trip be built at all, even if it takes more steps? If not, the model has an artificial ceiling.
  3. Does the interface ever ask a question the user hasn't yet signaled they care about (mode before they've added a second leg, traveler mix before they've added a second traveler)? If yes, disclosure is misordered, not missing.

Grounding those questions in the traveler's underlying job — as the Jobs to Be Done framework frames it — helps separate "this field is technically needed eventually" from "this field is needed right now," which is the actual disclosure boundary, not a guess about screen real estate.

Where the Complexity Cliff Actually Lives

Most teams don't discover the complexity cliff — the leg count or traveler mix at which the interface's assumptions break — until engineering has already built one linear flow and a real customer support ticket surfaces the edge case. Finding that cliff on paper, before code, is cheaper by an order of magnitude and is really a wireframing problem, not a backend problem.

Once the cliff is visible on paper, it's also worth stress-testing against a real disruption scenario — what happens to a saved five-leg trip when leg two's flight is cancelled — since multi-city itineraries compound the disruption-handling problem covered in designing for travel disruption by needing to re-flow every downstream leg, not just rebook one segment. And because the whole shape of this problem — search, compare, book, manage, resolve — sits inside the same journey a traveler walks end to end, it's worth mapping against the broader customer journey rather than optimizing the search screen in isolation; the traveltech landscape overview also frames where itinerary complexity fits against adjacent problems like loyalty and disruption in the complete guide to traveltech.

Key Takeaways

  • Complexity in multi-city trips is multiplicative, not additive — legs, travelers, date flexibility, and mode combine, so a three-city trip with per-leg flex can represent dozens of times more states than a single round trip.
  • Progressive disclosure means adding screens, not adding fields — a conditionally-visible field on the same screen still costs scan time; a new screen reached only by explicit action does not.
  • The single highest-leverage default is auto-filling the next leg's origin from the prior leg's destination — it removes the most repetitive step in building a multi-city trip.
  • Saved-trip state must be a durable object, not session memory — per-leg selections, traveler assignments, and price snapshots all need to survive interruption independently.
  • Two failure modes sit on either side of the right design — over-simplifying hard-caps real trips away, over-exposing scares off simple bookers; test both before shipping.
  • Find the complexity cliff in lo-fi wireframes before engineering commits to a data model — sketching the branching states cheaply is far less costly than discovering the ceiling in production.

Frequently Asked Questions

What is multi-city itinerary UX and why is it harder than round-trip search?

Multi-city itinerary UX is the design of search and booking flows for trips with three or more connected legs, mixed travelers, or mixed transport modes. It's harder than round-trip search because each additional axis — legs, travelers, flexibility, mode — multiplies the number of valid trip states rather than simply adding one more field to fill in.

How many legs should a multi-city search form support by default?

Design the data model to support an arbitrary number of legs, but design the default screen for one leg and reveal additional legs only when a user taps "add another city." Hard-coding a cap like three legs blocks real trips; showing all possible legs by default overwhelms the common single-leg case.

What's the difference between progressive disclosure and just hiding a feature?

Progressive disclosure reveals an option in response to a clear signal that the user needs it (adding a second city reveals per-leg controls), while hiding a feature removes it from the visible flow with no path to discover it. The test is whether a motivated user can always find and reach the complex option, just not by default.

How should a multi-city itinerary handle a flight cancellation on one leg?

A saved-trip object should treat each leg as independently re-bookable while re-checking downstream legs for connection validity, since cancelling or rebooking one leg in a multi-city trip can invalidate the timing of legs that follow it. This is the same durable trip-state requirement that makes saved itineraries resumable in the first place, just triggered by disruption instead of a user edit.

Should date flexibility apply to the whole trip or to individual legs?

Default flexibility to individual legs, since most multi-city trips are anchored by at least one fixed commitment (a meeting, a connecting flight) even when other legs are genuinely flexible. Applying flexibility trip-wide by default forces users to fight the interface to fix the one date that actually matters.