Source code of www.eclavin.com, a free study website for the WSET wine exams run by Eclavin.
Eclavin is an independent, unofficial study resource. It is not affiliated with, endorsed by, or sponsored by the Wine & Spirit Education Trust (WSET). WSET is a trademark of the Wine & Spirit Education Trust.
As of September 2026:
- 200 practice questions, 100 for WSET Level 1 and 100 for Level 2, each on its own page with the answer and a worked explanation, in English and Korean (Level 1, Level 2).
- Practice exams: a 20-question sample per level with instant marking (practice).
- 14 study guides in English: level comparisons, study plans, the tasting method, food and wine pairing (guides).
- A 20-term glossary in English and Korean (glossary).
- Profiles of 12 grape varieties and 12 wine regions in English (grapes, regions).
- An exam facts table (question counts, exam length, pass marks, study hours) that links to the official WSET qualification pages it is based on (exam facts).
The questions are original. They are written in the style of the multiple-choice exams and follow the topics of the published Level 1 and Level 2 specifications; they are not copies of real exam papers. The separate Eclavin iOS app (App Store) has 2,000+ questions across Levels 1, 2 and 3.
Machine-readable summaries: llms.txt, llms-full.txt, sitemap, RSS feed of the guides.
Corrections and questions: support@eclavin.com.
- Next.js App Router (
src/app). Question text lives in Markdown undersrc/content(l1,l2in Korean,l1_en,l2_enin English). - Guides, glossary terms, grapes, regions and practice pages are driven by registries in
src/lib/*Config.ts. The sitemap,llms.txt,llms-full.txtand the RSS feed are generated from the same registries, so a new page appears in all of them. src/lib/site.tsholds the site-wide facts: the one Organization entity (@idhttps://www.eclavin.com/#organization), the WSET entity used only as a subject, question counts, and helpers for titles, descriptions and share images.- Bilingual pages take
?lang=enor?lang=ko; without it, visitors from Korea get Korean and everyone else English.src/proxy.tspasses that choice to the root layout so<html lang>matches the page. English-only sections are prerendered. - Share images are drawn per page by
src/app/api/og/route.tsx.
npm install
npm run dev # local development
npm run build # production build
npm run gate # build, serve locally, and run the SEO checks on every page
npm run deploy # gate, then deploy to Vercel, tell IndexNow about new or changed pages, and re-check the live site
npm run check:seo -- https://www.eclavin.com # the checks alone, against any running copyDeploys are run by hand; pushing to GitHub does not deploy. The gate stops a deploy when a page
answers an error, has a noindex, a canonical or <html lang> that does not match it, JSON-LD that
does not parse or FAQ markup that differs from the text on screen, a duplicate or out-of-range
English title (50-60 characters) or description (150-160), no share image, no not-affiliated
notice, or a broken internal link. SEO_GATE_SKIP=1 npm run deploy skips it in an emergency.
Environment variables (set in Vercel):
NEXT_PUBLIC_POSTHOG_KEY: analytics.ADMIN_PASSWORD: optional. Without it the/adminarea stays locked.NEXT_PUBLIC_SUPABASE_URL,NEXT_PUBLIC_SUPABASE_ANON_KEY: optional page-view logging.