Localized home pages (/es, /fr, /de, /it, /pt) with server-rendered intro, how-to-play and FAQ plus FAQPage/WebApplication JSON-LD and hreflang. Puzzle archive at /archive with answer pages (/puzzle/N) for past days only and replays (/play/N) that never touch stats or the daily streak. Challenge loop: shared results link back as /?challenge=<code> and the result screen shows a head-to-head verdict. Also adds robots.txt, sitemap.xml, the PWA manifest and icons, a compact share text with WhatsApp/X/copy channels, a next-puzzle countdown, the social-proof play counter and a spoiler-free /api/teaser for daily posting. Refs #1 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QvQ1ErZNRUcWgCEkJ9uyrn
4.0 KiB
hidden11
Daily football lineup puzzle built with Next.js, React, TypeScript and Tailwind CSS.
Player data provenance and clue rules are documented in docs/data-sources.md.
Growth features
- Localized home pages:
/(en) plus/es,/fr,/de,/it,/pt— server-rendered intro, how-to-play and FAQ (FAQPage JSON-LD) with hreflang alternates on every home. - Archive:
/archivelists past puzzles;/puzzle/<n>publishes answers for past days only (today and future 404);/play/<n>replays a past puzzle without touching stats or streak. - Challenge loop: shared result links (
/r/<code>) offer "Accept the challenge" →/?challenge=<code>. If the challenge matches today's puzzle, the game shows the rival's score and a head-to-head verdict on the result screen. - Compact share text: one line per difficulty with the final attempt grid — built in
lib/share.ts. - PWA:
app/manifest.ts+ icons inpublic/(regenerate withnode scripts/generate-icons.mjs). - Daily teaser:
GET /api/teaserreturns a spoiler-free localized teaser for today's puzzle (first Easy clue).deploy/n8n-daily-teaser.jsonis an importable n8n workflow that posts it daily through the Postiz public API (setPOSTIZ_API_KEYin n8n and fill in the integration ids inside the Code node).
Local development
npm install
npm run dev
Open http://localhost:3000.
Optional analytics env vars:
NEXT_PUBLIC_GA_MEASUREMENT_ID: GA4 measurement ID, e.g.G-XXXXXXXXXXNEXT_PUBLIC_CLARITY_PROJECT_ID: Microsoft Clarity project ID
Optional feedback env vars:
N8N_FEEDBACK_WEBHOOK_URL: n8n webhook URL used to receive feedback submissions
Optional social-proof counter env vars:
N8N_PLAYS_WEBHOOK_URL: n8n webhook URL backing the daily play counter shown on the result screen ("N people played today"). The webhook receives{ action: "get" | "increment", date: "YYYY-MM-DD" }and must respond with{ count: number }. When unset, the counter line is simply hidden — no number is ever fabricated.
Optional sponsor env vars:
NEXT_PUBLIC_SPONSOR_ENABLED: set tofalseto hide the sponsor slotNEXT_PUBLIC_SPONSOR_NAME: sponsor name shown in the slotNEXT_PUBLIC_SPONSOR_TAGLINE: short sponsor copyNEXT_PUBLIC_SPONSOR_CTA: sponsor button textNEXT_PUBLIC_SPONSOR_URL: outbound sponsor URLNEXT_PUBLIC_SPONSOR_LABEL: small label above the sponsor name
Production build
npm run build
npm start
Docker
docker build -t hidden11:latest .
docker run --rm -p 3000:3000 hidden11:latest
CI/CD
Gitea Actions workflow:
.gitea/workflows/build-and-push.yaml- Builds on
main - Pushes:
gitea.alexandre-vazquez.cloud/alexandrev/hidden11:<git-sha>gitea.alexandre-vazquez.cloud/alexandrev/hidden11:latest
Required Gitea repository secrets:
REGISTRY_USERNAME:alexandrevREGISTRY_TOKEN: token with package/container registry permissions
Create/read tokens from pass; never commit credentials.
Kubernetes
kubectl apply -f deploy/k8s
The app is configured for:
- Namespace:
hidden11 - Ingress host:
hidden11.app - Ingress class:
public - TLS secret:
hidden11-tls
To enable analytics in Kubernetes, create a secret named hidden11-analytics in the hidden11 namespace with:
NEXT_PUBLIC_GA_MEASUREMENT_IDNEXT_PUBLIC_CLARITY_PROJECT_ID
To enable feedback submission, create a secret named hidden11-feedback in the hidden11 namespace with:
N8N_FEEDBACK_WEBHOOK_URL
To configure the sponsor slot in Kubernetes, create a secret named hidden11-sponsor in the hidden11 namespace with any of:
NEXT_PUBLIC_SPONSOR_ENABLEDNEXT_PUBLIC_SPONSOR_NAMENEXT_PUBLIC_SPONSOR_TAGLINENEXT_PUBLIC_SPONSOR_CTANEXT_PUBLIC_SPONSOR_URLNEXT_PUBLIC_SPONSOR_LABEL
ArgoCD
kubectl apply -f deploy/argocd/application.yaml
The ArgoCD Application includes ArgoCD Image Updater annotations for:
- image:
gitea.alexandre-vazquez.cloud/alexandrev/hidden11 - strategy:
digest - write-back:
argocd