SEO7.ES — Web, SEO, AI & Automation
Skip to content

Case · Language school

A two-language school where everything runs on one base.

YLC Valencia — мобильная версия
🌐

3 languages out of the box

🎓

Student portals

🛒

Course store with checkout

🤖

Bots & CRM for sign-ups

Trilingual website, student and teacher dashboards, AI Telegram and WhatsApp bots, store, payments and a CRM with scheduling — all on one backend.

ylcvalencia.es is a full ecosystem for a bilingual center in Valencia: a trilingual website, dashboards, bots, a store, payments and an in-house CRM with scheduling, attendance and payroll.

YLC Valencia — десктоп

Want a similar project?

Take a short brief — we’ll come back with a plan and a quote.

ylcvalencia.es is the platform of the bilingual Your Language Club centre in Valencia. A public site in three languages, student and teacher dashboards, Telegram and WhatsApp bots with an AI assistant, a shop with online payment, an in-house CRM with schedules, attendance and payroll, a blog content engine and a B2B contract system all run on one backend and a shared database. The school runs two strictly separate tracks: Spanish for Russian-speaking and English-speaking expats, and English for Spaniards.

Client: Your Language Club, Valencia · Site: https://ylcvalencia.es · Category: platform

The short version

  • Two tracks in one system: Spanish for expats and English for Spaniards never mix anywhere.
  • Three languages on the public side: Russian, Spanish and English.
  • Student and teacher dashboards with schedules and attendance.
  • Bots on Telegram and WhatsApp with an AI assistant.
  • A course shop with online payment and B2B contracts for companies.
  • An in-house CRM, including a payroll module for teachers.

Technology stack

  • Frontend: Next.js 16 (App Router, Turbopack, standalone output) + React 19 + TypeScript 6, Tailwind CSS 4 (@theme inline), custom design, fully responsive.
  • i18n: next-intl 4, three UI locales (RU / ES / EN), auto language detection (navigator.language → Accept-Language → IP), hreflang.
  • Backend: Express (Node 22) — REST API for briefs, ideas, prices, CRM, media uploads and admin endpoints.
  • Database: Prisma 6 + SQLite (persistent volume on the VPS), PostgreSQL 16 + Redis 7 in Docker for heavier modules.
  • Telegram bot: grammY (TypeScript) with context memory.
  • WhatsApp bot: WhatsApp Business Cloud API.
  • AI: OpenAI GPT + Anthropic Claude, RAG on the school's materials, two assistant presets (Spanish teacher / English teacher).
  • Payments: Stripe + a local Spanish acquirer, idempotent webhooks.
  • Email: SMTP + Mailgun, DKIM / SPF, MailHog for development.
  • Automation: n8n (briefs, leads, broadcasts, nightly jobs).
  • Infrastructure: Contabo Cloud VPS, Ubuntu 24.04, pm2 (native web + brief-api) + Docker Compose (Postgres / Redis / n8n), nginx, Let's Encrypt SSL.
  • CI/CD: GitHub Actions — auto-deploy on push to main (tsc-check → build → rsync → pm2 reload → healthcheck), one deploy at a time.
  • Analytics and monitoring: Plausible, healthcheck endpoints, pm2 log rotation.

How it started

A language school in Valencia lives in two worlds that never touch. Russian-speaking and English-speaking expats learn Spanish; Spaniards learn English. Different interface language, different copy, different channels and different expectations of how they will be spoken to.

Building two websites for that would have doubled the work and produced two sources of truth about schedules and payments. So the tracks were separated inside one platform: a shared database and backend, but a distinct path for each audience.

The second half of the job was administrative. Schedules, attendance and teacher payroll had lived in spreadsheets, and corporate clients needed separate accounting by contract. All of it moved into a CRM built into the same system the student learns in.

Full list of implemented features

🌐 Website and pages

  • Three UI locales (RU / ES / EN) with auto language detection and redirect to /<locale>/
  • Two separate tracks: Spanish for Russian speakers / expats (/ru/, /en/), English for Spaniards (/es/) — catalogues, tone and SEO semantics never mix
  • Video hero on the first screen + Spanish-cities slider with auto-rotation
  • Course catalogue: 10 templates for Spanish + 9 for English, a dedicated page for each course
  • 8 SEO landing pages for levels (A1 / A2 / B1 / B2 × 2 tracks) with course lists and FAQ
  • Interactive course-picker quiz (5-step wizard → enquiry on WhatsApp)
  • Free level test, "About the school", "Methodology", "Teachers" pages (8 profiles with video intros), "Activities", "Calendar", "Gallery" (replaces 360° tours)
  • Kids' day-camps for school holidays, no accommodation
  • Feed of 43 real Google reviews (swipe on touch, equal-height cards)
  • Feed of Spanish-speaking countries with photographs
  • Talking mascot FAB (60 lines, tilts towards the cursor, swipe-hides for 10 minutes)
  • FAQ engine: 12 sets across pages, 15 questions × 3 locales, native <details>, FAQPage markup
  • Preloader with a shimmer effect, ScrollToTop, a 404 page
  • Full mobile adaptation: top branding bar, bottom tab-bar sized to the viewport, bottom-sheet navigation with lock-scroll and safe-area

🔐 Authentication and roles

  • Login by phone or email + password, password recovery
  • 6 roles with capability bits: guest, student, teacher, admin, director, developer
  • Capability-based navigation filtering: each user only sees the sections they have access to
  • Dev mode that switches the effective role for testing permissions
  • Per-user permission overrides on top of the role (director-granted access)

👤 User dashboard

  • Student profile, history of courses and payments
  • Teacher dashboard: own schedule, own groups, attendance
  • Sticky tab navigation, jump to the admin for staff
  • Notifications via Telegram and email

🛠 CRM and admin

  • A single server-side AdminShell skeleton with sidebar navigation for every admin section
  • Leads: kanban pipeline with HTML5 drag-and-drop across stages
  • Students: dedicated page with filters (track, CEFR level, status, search), a student modal card with a ?student=<id> deep-link
  • Schedule: 7-day × time grid, drag-and-drop of groups across cells, block transfer, colour by CEFR level, sticky group-palette by level (A0–C2), "My schedule" filter by teacher
  • Attendance: pick a group and a date → bulk "present / absent" marking
  • Teachers: payroll module — hours and ≈€/month are computed automatically from schedule slots at a €/hour rate
  • Groups, enrolments, payments, B2B contracts — full CRUD
  • Broadcasts: audience collection from CRM by segments → wa.me / t.me deep-links
  • Single source of truth for status and level colours (Badge, levelColor, statusColor)
  • All admin pages gated via getMe / capability-check with redirect to login

🛒 Online store

  • Catalogue of 4 categories: textbooks, merch (with size selection), gift cards, digital materials
  • Product page in 3 locales (title / description / price in euros), size variants, photos
  • CRUD product admin with a modal editor and image upload (base64 → local volume, MIME validation, 5 MB limit, cache headers)
  • Cart, checkout, success / failure pages
  • Payments via Stripe + a Spanish acquirer, idempotent webhooks
  • Fallback to a static catalogue when the backend is unreachable

📝 Content engine (blog)

  • A single post model: one record = three locales (RU / ES / EN) bundled together
  • CRUD admin with locale tabs, draft / published statuses, auto-stamping the publication date
  • Cover images via image upload to the VPS
  • Server-side rendering of posts from the API with a static fallback, content picked by locale
  • "Related articles" block, breadcrumbs, Markdown paragraphs

🤖 Bots and AI assistant

  • Telegram bot (grammY): course menu, schedule, profile, referral link, trial-class booking
  • WhatsApp bot (Business Cloud API): most of the website's features inside the messenger
  • AI assistant with two presets (Spanish teacher for Russian speakers / English teacher for Spanish speakers), context memory and RAG over the school's materials
  • Proxy to OpenAI / Anthropic, conversation logging

📅 Schedule and calendar

  • Calendar of dates, schedule and Spanish public holidays on the public site
  • Internal group schedule in the CRM with block transfer and a teacher filter

🧾 Briefs, ideas and notes

  • Briefing form with server-side storage, admin view of every brief
  • Idea collection for the roadmap from the website, admin processing (processed, addedTo, note)
  • Shared notes for the design-system screens (11 sections) with authorship

🎨 Design system

  • 11 screen sections on a single /design/ page
  • Atoms: Button (continuous flash + shadows), Arrow, Logo, SpeechBubble, Highlight, CefrBadge, PhoneFrame, ScaleRow and others
  • Design tokens — CSS variables --ylc-*, adaptive sizes via clamp() everywhere
  • Online CSS editor for tweaking the design without redeploying

🔍 SEO / GEO / AEO

  • Sitemap.xml + robots.txt, canonical + hreflang between RU / ES / EN
  • Schema.org markup: EducationalOrganization, Course, BlogPosting, FAQPage, BreadcrumbList
  • OG / Twitter meta tags, server prerender for correct sharing previews
  • AI Overviews readiness, llms.txt
  • 8 SEO landing pages for levels + course pages aligned with track semantics

⚡ Performance and media

  • Standalone output (minimal Docker / Node build)
  • Self-hosted fonts (Onest, Caveat, JetBrains Mono) via next/font — no render-blocking
  • Content photos loading="lazy" + decoding="async", hero video preload="auto" + fetchpriority="high"
  • Desktop / mobile video chosen via matchMedia, leaf-shaped photo mask via SVG clip-path
  • Lazy Prisma client — a database error does not bring the API down

🛡 Security and reliability

  • RBAC on capability bits + per-user permission overrides
  • Basic Auth on admin endpoints through nginx
  • Idempotent payment webhooks, upload validation (MIME + size)
  • Secrets outside git (a local vault), masking in logs and commits
  • Healthcheck endpoints, pm2 auto-restart via systemd on reboot

📦 Infrastructure / DevOps

  • Monorepo (apps/web + apps/brief-api), pm2 natively + Docker Compose for the databases
  • Auto-deploy via GitHub Actions: tsc-check → next build → rsync → pm2 reload → healthcheck
  • Concurrency locks on deploy, pnpm-store cache
  • nginx routing (web :3000, brief-api :4000, static roadmap presentation), SSL with auto-renewal
  • Manual rsync deploy as a fallback; log rotation; persistent data volumes

Results

MetricValue
Teaching tracks2, separated by audience
Public-side languages3: Russian, Spanish, English
Dashboard types2: student and teacher
Bot channelsTelegram and WhatsApp
Paymentonline, in the course shop
Corporate accountinga B2B contract system
Administrative sideCRM with schedules, attendance and payroll

More about this case

The full story — why the school's Russian pages sell Spanish, the Spanish pages sell English, and why they are not translations of each other: read the article on LinkedIn.

Not sure where to start?

We’ll review your case in a free consultation and propose a solution.

Itemised estimate

47 itemsTimeline: ~1 month
À la carte (separately)€15.250
Bundle saving−€9350
Turnkey package€5900

Prices per our list. Each module costs more separately: integrations, management, overhead. As one project on a single backend it’s cheaper. Exact quote for your case after the brief.

The more features, the better the bundle

SeparatelyBundle price
Минимум · €390Стандарт · €1490Премиум · €4990€15.250−€9350This project€5900Scope of features →47Cost, €

Bought separately, cost grows linearly. As a bundle it plateaus: shared architecture, one backend, code reuse. So the more features, the wider the gap — and the bigger your saving. This project (41 features) is already at the plateau.

Frequently asked questions

A trilingual website, student and teacher dashboards, Telegram and WhatsApp bots with AI, an online store, payments, a CRM with schedule and payroll, and a blog content engine — all on a single backend and one shared database.

Related projects.

Ready for your project?

Leave a request — we’ll estimate the timeline and price for your business.