A trial is a length of time. Thirty days, fourteen days, pick your number. That is what the word does in every SaaS pricing page the reader has seen before arriving at ours.
Ours is not a length of time. It is one quiz session. There is no day count in the schema, no expiry job, no trial_ends_at, nothing anywhere in the product that counts down. The free thing we offer is a quantity of one, and a visitor who never uses it still has it in a year.
We call it a trial anyway, in some places and not others, and I went looking for how many places.
In the database
The venue row carries three fields about this one concept:
subscription_status text not null default 'trial'
plan_type text not null default 'trial'
trial_used boolean not null default false
Two separate columns whose default value is the string trial, and a boolean that records whether the thing has been spent. Different parts of the app ask different columns. The billing page tests subscription_status === 'trial'. The limit lookups take plan_type. They agree today because both are set together at signup and moved together by the Stripe webhook, and nothing enforces that they must.
There is also a fourth, older column named plan, nullable, carrying a comment that says to use the venue's subscription status instead. It is still in the table.
In the pricing module
The money file is the most careful of the three places. It defines the trial's price as zero, with a comment saying it must stay exactly zero in every currency, and then it defines the type of a plan that can actually be sold as everything except the trial:
export type PaidPlanType = Exclude<PlanType, 'trial'>
The product names that reach Stripe and a customer's invoice cover Pro and Ultimate only. The trial is modelled, correctly, as a thing the type system will not let you charge for. That zero also had to be defended elsewhere: the local-currency rounding that turns £30 into €36.99 would happily turn £0 into €0.99, so there is a guard for a price of zero whose entire job is to stop the free session being sold for a euro.
In the copy, where it mostly is not
Here is the part I did not expect. Across the 72 pages in our sitemap, the word "trial" appears on exactly four pages:
- the homepage, three times
- the pricing page, three times
- the terms, twice
- one of the free question pages, once, in a quiz question that has nothing to do with billing
The other 68 pages never use it. They end with a button labelled "Start free, no card needed", which appears 68 times across 68 pages, and the phrase "no card" appears 113 times. The content side of the site sells this as free, not as a trial.
The button
Go to pub-trivia.app/pricing. There are two cards, Pro and Ultimate. There is no third card for the free tier. Both paid cards carry the same button:
Start free trial
and under it the same line: "One free session included. No card needed to start."
So the only place the word trial is used as a call to action, it sits on a card for a monthly subscription, which invites the obvious reading: that pressing it trials that plan for a while. What it actually starts is the free session, which is its own tier with its own limits, and which is the same free session whichever of the two buttons you press.
The FAQ further down the same page is the clearest writing we have on the subject, and it never uses the word in the answer:
Every new account gets one free session: a complete quiz night, hosted exactly the way a paid one is, with all thirteen built-in question packs and up to ten tables. The two things it does not include are custom packs of your own and a second session.
That paragraph is a quantity, a scope and two exclusions. It is a good answer to a question titled "Is there a free trial?", which is the only reason the word is on the page at all: because that is what people search for.
The terms take the same shape under a heading that says Free trial: one free quiz session, no payment method, expires once that session is used. The heading is a period, the sentence under it is a counter.
In the dashboard
Behind the sign-in, where there is no SEO reason to use the word, it comes back:
You have one free trial session remaining.
Your free trial has been used. Upgrade to Pro to keep hosting.
Free trial used
Three surfaces, three phrasings, all correct, all saying "trial session" because "trial" alone would be wrong and "session" alone would not explain which one.
What the grep adds up to
92 case-insensitive occurrences of trial in the TypeScript, across 29 files, leaving out tests and seed data. Four of 72 public pages. Two database columns, one boolean, one dead column. One type that exists to exclude it, and one zero-price guard to protect it.
For one feature that can be described in six words: your first quiz night is free.
Would I rename it?
Not in the database, where trial is the default of two columns, lives in a Stripe webhook, and is pattern-matched in a dozen files. The cost is a migration plus every call site, and the benefit is zero, because no customer reads a column name.
In the copy, yes, and the audit tells me where. The 68 pages that say "Start free, no card needed" are right. The two pricing surfaces that say "Start free trial" are inviting a reader to expect a period of time, and the sentence directly under the button already says what it really is. The FAQ heading can keep the word, because it is a question people type into Google, and the answer is already honest about the arithmetic.
What made it findable was not reading the code. It was counting the same word on the live pages and in the source and noticing the two counts describe different products.
You can do the counting half yourself in a minute: open /pricing and search for "trial", then open any guide and search for it there.
Top comments (0)