Live demo: https://subtitled-zwlt.onrender.com Code: https://github.com/swapnilchaudhari007/subtitled
Inspiration
Most people who start a new language quit within a few weeks. Every "learn Japanese with media" guide gives the same advice: watch Spirited Away, listen to some J-pop, read Norwegian Wood. Fine picks, but they're the same for everyone, so they're nobody's picks.
The people who stick with it usually stumble onto something in the new language that feels like what they already love in their own. They keep going because they want to know what happens next, not because they're "studying".
Language teachers call this comprehensible input, and the research is pretty clear that you need hundreds of hours of it. The hard part isn't access to content — it's finding content you'll actually stick with. That's a taste problem, and taste is exactly what Qloo knows about.
What it does
You tell Subtitled:
- the language you're learning (Japanese, Korean, Spanish, French, German, Hindi, Portuguese, Italian, Mandarin),
- your level,
- two to six things you love — any medium, any language,
- optionally, your city.
An agent then:
- Looks up each favourite in Qloo and pulls the tags they share. That becomes your taste fingerprint — "dark humour, slow burn, antihero" rather than "drama".
- Crosses the language line. It asks Qloo's Insights API for films and series released in the target country, and for artists, books and podcasts carrying the right language tags — all ranked by affinity to your favourites.
- Checks and retries. Empty result? It loosens the popularity floor, tries another country format, or turns the language filter into a soft signal and then throws out anything that drifted back into English. Every step shows up live on the page, so you can see what it did and why.
- Builds a 4-week plan for your level. Beginners start with music and familiar-genre films. Intermediate learners switch to target-language subtitles and podcasts. Advanced learners get books and native-speed audio. If you gave a city, the last week sends you to a restaurant there to order in the language.
Every pick shows its Qloo taste-match score and which of your tags it shares. Next to your plan, a small box shows "what everyone else gets told" — the generic list — so you can see the difference.
How we built it
- Plain Node.js server with no dependencies. The Qloo key stays on the server; the browser never sees it.
- Qloo endpoints:
/search(resolve favourites + autocomplete),/entities(tags for the fingerprint),/v2/tags(find language tags like j-pop or korean literature),/v2/insightswithsignal.interests.entities,filter.release_country,filter.tags,filter.popularity.minandfilter.location.query. - The agent is a plan → act → check → retry loop. Each Qloo call is a tool; each attempt has a stricter-to-looser fallback list, and the agent remembers which country format worked so it doesn't waste calls next time.
- Results stream to the browser as newline-delimited JSON, so you watch the agent work instead of staring at a spinner.
- Optional Gemini step writes a short coaching note, but it's only given the titles Qloo returned and told not to add any. Without a Gemini key, a template writes the note.
- In-memory cache and a per-IP limit so a demo doesn't burn through the quota.
- A test runs the full agent against a fake Qloo server to check the retry logic.
Why Qloo is the whole point
Without Qloo this is a listicle. An LLM on its own will give everyone the same famous titles. It doesn't know that someone who loves Breaking Bad and Arctic Monkeys might do better with a Japanese crime series and a Japanese indie rock band than with a Ghibli film. Qloo's cross-domain taste graph is what makes that jump possible — from an English TV show to a Japanese band to a ramen place in your city.
Challenges
- Music, books and podcasts don't have a "country" field, so I had to find the right language tags first with the tag search, and then double-check results actually carried them.
- Some language + medium combinations come back thin. Rather than pad the plan with made-up stuff, the agent says so in an "honest notes" section.
- Keeping the agent visible. A bare list of results feels like magic in a bad way, so every step the agent takes is streamed to the page.
Accomplishments I'm proud of
- It gives two people learning the same language completely different plans.
- The agent tries several looser queries before it gives up on a shelf.
- No build step, no dependencies — clone, add a key, run.
What I learned
Taste data is much more useful when you cross a boundary with it — from one medium to another, or one language to another. Recommending more English crime shows to a crime fan is easy. Getting them to a Japanese one they'll love is where it gets interesting.
What's next
- Save plans and tick things off week by week.
- Difficulty signals per title (speech speed, subtitle availability).
- Plans for heritage learners — people reconnecting with a family language — seeded from what their parents used to watch and listen to.
Limitations
Qloo describes what audiences who like X also like; it's a strong hint, not a promise. "Released in Japan" doesn't always mean "in Japanese". No accounts, no tracking, and Qloo responses are never stored in the repo.
Built With
- css
- html
- javascript
- node.js
- qloo
- render
Log in or sign up for Devpost to join the conversation.