The One Fact
I love The Lord of the Rings more than I'd like to admit, yet I still stumble on things I didn't know about the legendarium, or things I knew but forgot. So I built a tiny web app to scratch that itch: The One Fact, a self-hosted app that shows one fact a day from Tolkien's Legendarium, every day.
No feed to doomscroll, no newsletter to unsubscribe from. Just one fact, every day, on a quiet page.
Death after Nirnaeth - Glóredhel, daughter of Hador, married Haldir of the House of Haleth and became the mother of Handir, ancestor of Brandir the Lame. After Haldir was slain in the Nírnaeth Arnoediad, she died of grief on hearing the news.
Glóredhel · Hador · House of Haleth · Nírnaeth Arnoediad · Brandir the Lame
How it works
It's a small Laravel app with one job that runs once a day:
- Grab a random article from Tolkien Gateway.
- Hand the page text to an LLM and ask it to pull out one self-contained fact plus a few tags.
- Store it in SQLite with today's date.
The newest fact is shown on a minimal Tailwind page (no JavaScript, no accounts) and exposed as JSON at /api/fact if you want to build on it.
The AI part runs on the new official laravel/ai package, so you bring your own provider (OpenAI, Anthropic, Gemini, Mistral, Groq, Ollama, whatever) by setting one env var.
The Cloudflare plot twist
Halfway through, Tolkien Gateway put itself behind Cloudflare's JavaScript challenge. Suddenly every server-side fetch came back as "Just a moment…", the page only loads in a real browser. Classic.
The fix was a little inelegant but effective: a FlareSolverr sidecar that runs headless Chrome, solves the challenge, and hands back the real HTML. The app talks to it over the internal Docker network, and Tolkien Gateway stays the source of truth.
Run your own
It's two containers in a docker-compose.yml (the app + FlareSolverr):
docker compose up -d
Open http://localhost:8467 and you're done. The SQLite database lives in a mounted ./data folder, so backing up your facts is just copying a file. The image is a lean ~217 MB Alpine build with the daily cron baked in — no extra moving parts on your side.
Full instructions and source are on GitHub: github.com/mydnic/the-one-fact.
One fact a day. Not bad for a Tuesday in the Third Age.