ChinesePod
A Mandarin learning service built on a large lesson library, sold to self-paced learners, corporate teams and schools from one site.

What they came with
The catalogue is the business, and it has been accumulating for two decades. Every lesson carries a dialogue, a vocabulary set, expansion notes and exercises, and nearly all of it sits behind a subscription. One library has to be sold three ways from the same site: a self-serve plan, a corporate programme and a school licence, and each buyer interrogates a lesson differently. A lesson page also has to be worth finding from search while the paid material stays paid.
What the build had to do
Six levels carrying the catalogue
The level grid is the primary taxonomy and the primary answer to where do I start. Each of the six levels states its own lesson count and a plain statement of what a learner can do at the end of it, so the block works as navigation and as a placement guide at the same time.
One lesson, five surfaces
A lesson record feeds a video or audio episode, a dialogue, a vocabulary set, expansion notes and exercises, and the home page carousel shows each of those as a real screen from the product. The same record renders five ways, with characters, pinyin and English toggled independently in each.
Two institutional lanes
Companies and schools each get a page with their own outcome language and their own quote form, and the required fields differ: learner count and company website on one, student numbers and institution address on the other. Each lane answers to a second URL as well, and the alias returns the same document byte for byte, so a campaign link can point at either name.
Auth that survives its own history
One client-side component serves signup, login and password recovery, choosing its view from the pathname and recognising the historic URL shapes the site has accumulated, including /accounts/signin, /log-in and /sign-up. It lifts a campaign id from either a signup path segment or a query parameter into a cookie, and it answers an existing-account response inline by offering recovery rather than throwing an error.
One price, three conversations
The pricing page carries a single priced learner plan beside three cards that resolve to a conversation rather than a number: teams, education, and a sample account. Those three have to sit level with a priced card without pretending to be one, which is what keeps the row readable.
Technical detail
Server rendering with no build step
Pages are rendered as HTML on Node and cached at nginx, which reports hits and misses through X-Proxy-Cache. There is no client framework and no bundler. Interactive parts are picked up declaratively instead: carousels and players are found by class and configured from data attributes, including per-breakpoint slide counts and a JSON player config, so a new section is markup and attributes rather than a component and a rebuild. Media is served from S3 and CloudFront, which keeps the heavy files off the application origin.
A versioned API as the only seam
The marketing site talks to the learning application through /api/v1/ and nothing else. The signup form posts JSON to /api/v1/entrance/signup and includes a confirmationRedirectUrl, which lets the backend aim the confirmation email at a different application build without touching the front end. The same component derives its API base from whether it is mounted at the root or under a path prefix, so one file runs in both positions.
Gating and indexing pulling against each other
Gated routes redirect to /login with a continue parameter and return the reader to the page they wanted. Against that, a generated sitemap index splits into pages, lessons, videos, community, pronunciation and twenty-three dictionary shards, and the public lesson page renders lesson id, level, summary, a vocabulary table with a play control on every row, and dialogue lines in characters, pinyin and English. How much of a paid lesson to render for an anonymous reader is the whole trade in that template, and it is decided per block rather than per page.
The stack
Application
Front end
Media and delivery
Measurement and discovery
- Sector
- Mandarin language learning
- Audience
- Learners, companies, schools
- Shape
- Marketing site, gated library
- Platform
- Node behind nginx



Something like this to build?
Tell us what runs today and where it hurts. An engineer reads it and replies.