Read News, Learn English
- Role: Designer, Full-stack Developer
- Type: Side project — AI-powered web application
- Stack: Next.js 15, TypeScript, Drizzle ORM, Neon PostgreSQL, Anthropic Claude API, Clerk, Vercel
- Live site: news.estherh.dev
What is this?
A bilingual English learning platform that turns real international news into structured learning content — daily, automatically. Every day, headlines are fetched from sources like BBC, Guardian, and Al Jazeera, scored for teaching value by AI, and the best one is generated into a full lesson at three difficulty levels.
Each lesson features Nemo 🐠 and Octo 🐙 — a curious fish and a knowledgeable octopus — guiding learners through the news in English, with Traditional Chinese translations and vocabulary explanations throughout.
How it works
RSS Fetch
Headlines fetched from BBC, Guardian, Al Jazeera, Yonhap, DW...
AI Scoring
Claude scores each headline for teachability — no web search, plain text only
AI Generation
Top candidate → Claude generates bilingual lesson with web search at 3 levels
Published
Article saved to DB and published to frontend at 08:00 Taipei time
Challenges & Solutions
API cost optimization
The initial implementation used Claude's web_search tool at the headline scoring stage, making every daily run expensive. Refactored to fetch RSS directly on the server and pass raw headlines as plain text — scoring cost dropped significantly, with web search reserved only for article generation where current information actually matters.
Duplicate cron runs
Vercel Cron on the free tier doesn't guarantee exact timing and occasionally triggers multiple times per day. Added a guard that checks whether an article already exists for today before proceeding — any duplicate trigger silently skips without wasting API calls.
Removing rss-parser
rss-parser internally uses the deprecated url.parse() API, causing Node.js warnings on every cold start. Replaced with a lightweight custom regex parser using native fetch, eliminating the dependency entirely.
Teachability scoring drift
Early versions of the scoring prompt used vague criteria, which allowed celebrity gossip, weather reports, and horoscopes through. Rewrote the prompt with explicit rejection rules and a structured accept/reject framework — content quality improved significantly.
Accessibility
Built with WCAG 2.1 AA standards throughout:
- Semantic HTML with appropriate landmark regions
langattributes on English (lang="en") and Chinese (lang="zh-TW") content throughout- Tab interface with correct
role="tablist",aria-selected, andaria-controls" role="status"andaria-live="polite"for loading states- Colour contrast audited — all text meets 4.5:1 minimum ratio