Primary Flows
A primary flow is one important path that a user takes through the product, from the moment they arrive to the moment they reach their goal. This page describes the five paths that matter most. We did not invent these five paths from imagination. We chose them from the real entry-point data, which is the record of where users actually arrive on the site and what they do next.
Each flow below is written as a numbered sequence. It starts from where the user arrives and ends at the objective. In almost every flow the objective is the same: submit an application. For each flow we do two things:
- We name the current friction, which means the step where users struggle or leave today.
- We show the redesigned path, which is the smoother path we want to build.
The data showed us two very different kinds of user, and these two kinds shape every decision on this page:
- Comparison shoppers (gig). These users view gig job pages about 4.5 times per user. Because they look at many jobs and compare them, they need to scan and filter quickly.
- Careers visitors who arrive and then leave. These users arrive on one job page directly from Google, with no earlier context, and they view careers job pages only about 1.9 times per user. Because they see almost nothing else, they need a job page that is complete on its own and can turn a single visitor into an applicant without depending on any other page.
GA4, jodapp.com, Singapore, 90 days:
- Gig job detail pages: 15,032 views by 3,334 users = 4.5 views per user.
- Careers job pages: 4,984 views by 2,646 users = 1.9.
- Method: every careers job URL has
hqas its middle URL segment (careers jobs all get the placeholder outlethq), so the two groups are separated by URL structure — measured, not guessed.
The IA concepts behind this page
The flows use standard user-journey methods, plus two behavioural ideas for the apply step.
- User flows and task analysis are standard interaction-design practice for describing the path from arrival to a goal.
- Conversion funnel analysis comes from web analytics: measure how many users pass each step, and find where they leave.
- Record the application first, ask for the profile later uses deferred (lazy) registration and progressive disclosure, both established patterns for reducing sign-up friction.
- The Fogg Behavior Model describes the same idea: when we lower the effort needed to act, more users complete the action. (Fogg is a practitioner framework, not peer-reviewed theory; we use it as a description, not as proof.)
For the full list of concepts and sources, see Theory & Method Foundations.
Flow 1 — Direct-to-job apply (one session in four lands here)
The home page is the single most common landing page (27.8% of sessions). But 72.2% of sessions do not start on the home page, and 25.2% of sessions land directly on one job page. So for one visitor in four, a job page is the front door, and they arrive there from Google with no earlier context. We can see who they are: every top organic landing page is an NTUC FairPrice or McDonald's outlet job. An organic landing page is simply the first page a user reaches from an unpaid Google result.
Because the user often sees only this one page, the job page must be able to convert on its own. To convert means to turn a visitor into an applicant. The page cannot rely on any earlier page for context, because for many users there was no earlier page.
GA4, jodapp.com, Singapore, 90 days — landing pages:
- Home: 5,199 sessions (27.8%).
- Job-detail: 4,707 (25.2%).
- FAQ: 2,478 (13.3%).
/jobs: 1,927 (10.3%).- 72.2% of sessions do not start on the home page.
- Search Console: after the home page, every top organic landing page is an NTUC FairPrice or McDonald's outlet job.
- Arrive on a job detail page from search.
- Understand the essentials fast: pay, place (outlet), type. A daily-pay badge belongs here too, but it depends on an open business decision (see Taxonomy & Filters).
- Tap Apply (sticky on mobile). Sticky means the button stays visible on the screen while the user scrolls, so it is always within reach.
- Submit — objective complete.
- If unsure, similar jobs and more at this employer keep the user on the site instead of returning to Google.
Current friction. The current job page works against this flow in three ways:
- An ad slot sits between the job summary and the Apply button, so it interrupts the user at the exact moment they are ready to act. This slot is not plain AdSense: it renders
AdsCampaignPlacementDisplay, our own self-serve paid campaign placement (keyjob_detail_inline), and it falls back to Google AdSense only when no campaign is found. So "remove the ads" is not a simple frontend cleanup. The decision, to be made with the billing team as owner: confirm which placement keys have sold campaigns, remove only the AdSense fallback (it earns cents per day), and keep the paid-placement capability — it becomes the featured-distribution product later. - There is no sticky Apply button. For careers jobs the page has a single Apply button mid-page, so making it sticky is genuinely low effort. For gig jobs there is one Apply link per shift group, so a sticky button needs a product decision first (for example, a sticky button that scrolls to the shift list). Owner: product.
- There are no "similar jobs", so the roughly 3 in 4 users who view a job but never reach an apply gate have no next step to take, and they leave. (The exact funnel numbers, and a caution about how "started to apply" is measured, are in Flow 5.)
Flow 2 — Browse and compare (gig comparison shopper)
The /jobs list is the number one page on the site (35,914 views in 90 days), and it is also the page where we lose the most people: 53% of the users who reach it never open a single job, and on desktop the loss is worse (67%). This flow is about a specific goal: turning users who only browse into users who actually open a job.
- Land on home or the list.
- Narrow with a type or category chip (Gig, Food & Beverage, Daily pay). A chip is a small tappable button that applies one filter.
- Scan cards that clearly show pay, a daily-pay badge, and the outlet.
- Open one or several jobs to compare.
- Save or Apply.
Current friction. The current list makes scanning hard, so users cannot decide which job to open. We checked each claim against the code, so the list below says exactly what is weak:
- The job card is weak in a specific way, not in every way. Gig cards do show pay — the text "
{payFrom}daily" — and a "Benefits" insurance badge; careers cards show pay only when the employer opted in. The card shows only the last part of the area path (for example "Tampines"), never the outlet name or address. And no daily-pay badge exists, because there is no payment-timing field in the data model (an open business decision; see Taxonomy & Filters). So the missing signals are: pay on careers cards, the outlet name, and an honest daily-pay badge. - A paid ad placement is inserted after every 5th card as an extra item — one per page of ten. No job card is removed. (An earlier version of this page said an ad replaces every fifth card; that was wrong.) The insert still interrupts the scanning rhythm and pushes real jobs down by one slot. The fix follows the same ads decision as Flow 1: keep the paid-placement capability, remove the AdSense fallback. Owner: billing.
- There is no category chip, so the user cannot quickly narrow the list to the kind of work they want.
- The sort menu offers exactly "Latest Created" and "Latest Updated". There is no "Highest pay" sort, and the relevance ranking that already runs during a search is never shown as a "Best match" label (see Flow 3).
Flow 3 — Search for a role
Some users know the exact job title they want, so they type it into the search box. This flow serves those users.
- Type a role word ("cashier", "dishwasher").
- See best-match results first, which means jobs whose text matches the search word best are ranked on top.
- Refine by daily pay or outlet.
- Open and apply.
Current friction — a correction. An earlier version of this page said the relevance ranking is defeated by a newest-first sort. We checked the code, and that claim is wrong. The search uses pg_search, and pg_search injects relevance (rank DESC) as the primary ordering whenever a query is present; the chained newest-first ordering can never take effect during a search. So relevance already wins when the user types a search term. What is actually true today:
- Browsing without a query is newest-first. That is fine for browsing.
- When two jobs have equal relevance, the tie resolves toward the older job (the tiebreak is
id ASC). - The UI exposes no sort choices beyond "Latest Created" and "Latest Updated". There is no "Best match" label, and there is no "Highest pay" sort.
Because the ranking already works, the fix is small and mostly frontend. The decision: show a "Best match" sort label and make it the default whenever a query is present (no backend change — it only names what already happens), and add a "Highest pay" option (a small backend change: one more allowed order_by value).
Flow 4 — Browse by employer
Employer names make up about a quarter of search demand. Because this is such a large share, this flow makes browsing by employer a first-class path, not an afterthought.
Search Console, Singapore, 3 months:
- Employer-name queries — 627 queries, 13,612 impressions, 235 clicks.
- Specific-place queries — 139 queries, 1,033 impressions.
- Employer beats place about 13 to 1.
- Tap Companies (or a featured-employer rail on the home page). A rail is a horizontal row of items the user can browse across. The list page is titled Companies hiring now.
- Pick an employer (NTUC, McDonald's).
- See its jobs grouped by outlet. This matches how people actually search, for example "fairprice jurong east".
- Open a job and apply.
Current state. This flow is close to ready, because company pages already exist and the backend index is built. Two pieces are still missing:
- The featured-employer rail is not built yet. No spec exists anywhere for the featured flag — who sets it, where it is stored, and how it expires. The spec must be written first; after that, the build itself is small.
- Browsing by employer is not prominent in the navigation, so users do not discover it easily. On mobile, a logged-in user today has no path to Companies at all; the Navigation Hierarchy fixes this.
Flow 5 — The apply moment (redesigned to capture the lead first)
This flow is the sub-flow that sits inside every path above, because every path ends with the user applying. Today it is the point of deepest friction. To understand it, we must look at two funnels, not one. The old version of this page showed a single funnel, and that single funnel hid the most important fact: its top is mostly gig traffic, but its bottom is entirely careers.
- Job-detail views are mostly gig. About 75% of job-detail views are gig (15,032 views, 3,334 users) and about 25% are careers (4,984 views, 2,646 users).
- All applications completed on jodapp.com are careers. In 90 days, 18 users completed an application on jodapp.com (33
generate_leadevents). Only 7 of those 18 passed the full list → detail → form sequence; the other 11 landed directly on a job page or took another path. Both numbers matter: 18 is the site-wide total, 7 is the strict-funnel count. Against 2,646 careers detail users, 18 completions is a 0.68% conversion rate. - Gig applications complete on gig-partners.jodapp.com, not on jodapp.com: 146 users in the same period, which is about 4.4% of the 3,334 gig detail users. So the gig funnel converts at roughly six times the careers rate — and the gig funnel is the one without the profile wizard in front of the application.
GA4, 90 days:
- jodapp.com funnel: 3,011 list users → 1,417 job-detail (53% loss) → 347 "started to apply" (76% loss) → 18 completed site-wide (7 through the strict sequence).
- Caution: "started to apply" is the
form_startevent, which fires on the search form, login, and sign-up — never on job-detail pages. - It is a proxy for "reached the gate before applying", not a real apply-form start.
- Cross-host funnel: gig-partners recorded 146 completing users, about 60–65% of them (~97 users) traceable to the jodapp.com job list.
Current (blocking). For careers jobs, the real current sequence is longer than we first documented. We traced it in the code:
- Tap Apply → the user must log in.
- A new user signs up, which includes a 6-digit email OTP (a one-time passcode).
- After sign-up the user is not logged in. They are bounced back to the login form and must authenticate a second time. This is a hidden friction that the first version of this page missed, and it costs users at the exact moment they have just proved their email.
- Then the
/talent/setupwizard: 6 steps — Talent Information (including a required salary expectation), Work Experiences, Certificates, Skills, Educations, Confirmation. 3 steps are hard gates the user cannot skip: salary, education, and skills. Experiences and certificates are skippable. - Only then, back on the job page, can the user tap Apply again — and the application is finally recorded.
Redesigned (capture first, complete later):
- Tap Apply.
- Pass the lightest possible gate. A gate is a required step the user must complete; here it asks only for an email or phone number plus a one-tap verify. This records the application immediately, tied to the verified contact.
- There is exactly one login, not a gig login and a careers login. This is not a new idea of this IA: the analytics architecture already defines Principle D, "Fluid Identity" — one
Identities::Userthat carries both gig and careers personas. The two-account split exists only against the legacy gig-partners app. So this step does not invent a model; it aligns the login UI with the doctrine we already wrote down. - The application is recorded. At this point the objective is already complete for the business.
- Then ask 1–3 employer-defined screening questions. They come after the application is recorded, so they can never block it, and the answers are shown to the employer together with the application. The reason: the client complaint that started this work was "2 applicants, none qualified". Making applying easier increases volume but reduces the information per applicant; screening questions restore that information without adding a wall in front of the apply.
- Then invite the user to finish creating the account and complete their profile in small steps ("add your experience to stand out"). This invitation is never a required step that blocks the application.
The recorded application is the outcome the business wants. Any step that sits between the user's intention to apply and the recorded application is a pure loss, because every user who leaves at that step gives us nothing at all. The two funnels above prove the point with our own data: the gig funnel, which has no wizard before the application, converts detail viewers at ~4.4%; the careers funnel, which puts login, a second login, and a 6-step wizard in front of the application, converts at 0.68%. For this reason we move the login weight and the whole profile step to after the application is recorded, and we add a native apply event on jodapp.com so the moment of applying is measured where it happens.
What we can and cannot measure today — a correction. An earlier version of this page said the gig-partners handoff makes the gig funnel impossible to measure. That is not true, and the corrected statement has two parts:
- The cross-host funnel can trace about 60–65% of gig-partners completions (~97 of the 146 users) back to the jodapp.com job list. So we can already connect most of the gig funnel across the two hosts.
- What is missing is a jodapp.com-native apply event: an event that fires on jodapp.com at the moment the user acts to apply. Today jodapp.com records careers completions (
generate_lead), but it has no apply event of its own — so gig apply intent is only visible through the cross-host join, and careers apply starts are only approximated by theform_startproxy described above. Adding the native event is a Phase 0 item in the Prioritization Roadmap.
For gig jobs, tapping Apply still sends the user off-site to gig-partners.jodapp.com (one Apply link per shift group). Flows 1 to 4 are identical for gig and careers up to that moment; only the final step differs. Be precise about the status of this handoff: no document says it is temporary. Two documents currently make it permanent — the analytics architecture doc enforces the "Showroom (jodapp.com) / Checkout (gig-partners)" split, and the DNS domain list marks gig-partners.jodapp.com as "no-change". This IA proposes retiring the handoff as the end-state. Before any build issue is created, a migration decision doc must be written in docs/30-49-domains/35-gig/ (docs before issues). Until then, we show one single, consistent Apply button and treat the redirect as the current, documented behaviour.