Skip to main content

Overview

This guide walks you through signing up, creating a trip, searching for flights, and building your first itinerary.
1

Sign up for an account

Navigate to /auth/signup and create your account with email and password.
/home/daytona/workspace/source/frontend/app/auth/signup/page.tsx
async function handleSignup(e: React.FormEvent) {
  e.preventDefault()
  setError(null)

  if (password !== confirm) {
    setError("Passwords don't match.")
    return
  }
  if (password.length < 6) {
    setError("Password must be at least 6 characters.")
    return
  }

  setLoading(true)
  const supabase = createClient()
  const { error } = await supabase.auth.signUp({
    email,
    password,
    options: {
      emailRedirectTo: `${window.location.origin}/auth/callback`,
    },
  })

  if (error) {
    setError(error.message)
    setLoading(false)
    return
  }

  setSuccess(true)
  setLoading(false)
}
Check your email for a confirmation link. Click it to activate your account, then sign in at /auth/login.
2

Create your first trip

After signing in, you’ll land on the Dashboard at /dashboard. Click Create Trip to start planning.

Trip creation form

  • Destination: Search for a city or country (e.g., “Tokyo, Japan”)
  • Date mode: Choose exact, weekend, or flexible
  • Travelers: Select solo or group
/home/daytona/workspace/source/frontend/components/dashboard-home/new-trip-card.tsx
const handleCreateTrip = () => {
  const destination = draft.destination.trim()
  if (!destination) {
    toast.error("Enter a destination first.")
    return
  }

  const slug = destination
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/(^-|-$)/g, "")
  const id = `${slug || "trip"}-${Date.now().toString(36)}`

  const trip = createTrip({
    id,
    destination,
    dateMode: draft.dateMode,
    travelers: draft.travelers,
  })

  clearNewTripDraft()
  toast.success("Trip created.")
  router.push(`/trips/${trip.id}`)
}
The trip is saved to Supabase and you’re redirected to the trip overview page.
3

Search for flights

Navigate to the Flights tab (/trips/[tripId]/flights) to search for options.

Search setup

  1. Select one-way, round-trip, or multi-city
  2. Choose origin and destination airports from the dropdown
  3. Pick departure (and return) dates
  4. Set number of passengers
  5. Click Search flights
TripLoom calls the SerpAPI integration to fetch live flight offers from Google Flights.
/home/daytona/workspace/source/frontend/app/api/flights/serp/search/route.ts
export async function POST(request: Request) {
  const apiKey = getSerpApiKey()
  const body = await request.json()
  const slices = body.slices // [{ origin, destination, departure_date }]

  const params = new URLSearchParams({
    engine: "google_flights",
    api_key: apiKey,
    departure_id: slices[0].origin,
    arrival_id: slices[0].destination,
    outbound_date: slices[0].departure_date,
    adults: String(body.adults || 1),
    currency: "USD",
  })

  const res = await fetch(`${SERPAPI_BASE}?${params.toString()}`)
  const data = await res.json()

  return NextResponse.json({ ok: true, offers: data?.best_flights ?? [] })
}

Reviewing results

Results display in a sortable table with columns:
  • Route: Origin → Destination
  • Date: Departure date
  • Departure / Arrival: Local times
  • Duration: Flight duration
  • Stops: Number of layovers
  • Cost: Total price in USD
  • Airline: Operating carrier
Click an offer row to expand segment details, then click Save this flight to add it to your trip.
4

Build your itinerary

Go to the Itinerary tab (/trips/[tripId]/itinerary) to plan your day-by-day schedule.

Adding itinerary items

  1. Click Add Item
  2. Fill in the form:
    • Title: e.g., “Senso-ji Temple Visit”
    • Location: e.g., “Asakusa, Tokyo”
    • Day: Select which day of your trip
    • Time block: Morning, afternoon, or evening
    • Status: Planned, todo, or finished
    • Category: Sightseeing, food, commute, activities, etc.
    • Start/End time: Local date-time for the activity
    • Notes: Optional details
  3. Click Add item
/home/daytona/workspace/source/frontend/lib/trips.ts
export type TripItineraryItem = {
  id: string
  tripId: string
  dayIndex: number // 1-based day index
  timeBlock: ItineraryTimeBlock
  status: ItineraryStatus
  category: ItineraryCategory
  title: string
  locationLabel: string
  startTimeLocal?: string // ISO 8601 local datetime
  endTimeLocal?: string
  notes?: string
  sortOrder: number
  createdAt: string
  updatedAt: string
}

Drag-and-drop scheduling

The itinerary page uses React Big Calendar with drag-and-drop. You can:
  • Drag events to different days or times
  • Resize events to adjust duration
  • Click a time slot to create a new item
  • Filter by status (planned/todo/finished)
All changes are local until you click Save Changes.
Unsaved changes are discarded if you navigate away. Always click Save Changes before leaving the page.

Next steps

Configure authentication

Learn how Supabase Auth is integrated and how to customize it

Explore flight features

Deep dive into flight search, status tracking, and booking

Build advanced itineraries

Export to Google Calendar, manage categories, and optimize your schedule

Set up group travel

Invite travelers, manage approvals, and split expenses

Common issues

Check your spam folder. If using a test/dev Supabase project, confirmation emails may be delayed. You can manually confirm users in the Supabase dashboard under Authentication > Users.
Verify that:
  • SERPAPI_API_KEY is set in your .env.local
  • You selected airports (not just cities) from the dropdown
  • Departure date is in the future
  • Origin and destination are different
Ensure you clicked Save Changes before navigating away. The itinerary editor keeps a local draft until explicitly saved.

Build docs developers (and LLMs) love