Tech Stack

What Quote Gallery is built on, where each technology lives, and why it was chosen over the alternatives.

Core Framework

Nuxt 4

Frontend

App shell, file-based routing, SSR, server API routes, and modules system.

Why: SSR on public pages (authors, quotes, presets) is critical for SEO while the app stays SPA-fast once navigated. Nuxt server routes also host the REST API and payment webhooks without a separate server.

Vue 3

Frontend

Component model for every UI piece — pages, cards, modals, the slideshow, and the embed widget.

Why: Composition API + `<script setup>` keeps components concise and TypeScript inference works without boilerplate.

Backend & Database

Convex

Backend

Realtime database, serverless functions (queries / mutations / actions), file storage, scheduled crons, and HTTP endpoints — covering quotes, authors, billing, AI, notifications, and admin.

Why: Reactive queries push updates to the UI without writing subscription glue. The schema is TypeScript-first and the same types flow end-to-end from DB to component props.

Authentication

Better Auth

Full-stack

User sessions, social login (Google, GitHub, Apple), email / password, API key management, and account lifecycle.

Why: Self-hosted, TypeScript-native, and ships a first-party Convex adapter so auth tokens are verified inside Convex functions — no separate auth service to maintain.

UI & Styling

shadcn-vue

Frontend

The entire component library — dialogs, dropdowns, sheets, tooltips, cards, tables, and more.

Why: Components are copy-owned, not a node_modules dependency. Full control to adjust primitives without fighting a third-party API surface.

Tailwind CSS v4

Frontend

Utility classes for every layout, spacing, color, and responsive breakpoint decision.

Why: v4 moves config into CSS itself, making design tokens live alongside styles and removing the JS config file entirely.

reka-ui

Frontend

Headless primitives that shadcn-vue wraps — handles ARIA roles, keyboard navigation, and focus management.

Why: Accessibility is handled at the primitive layer, so components meet WCAG AAA without manual ARIA authoring on every consumer.

Lucide Vue Next

Frontend

Every icon in the app — navigation, actions, status indicators, and decorative elements.

Why: Consistent stroke-weight icon set that tree-shakes per import, so only used icons ship in the bundle.

State Management

Pinia

Frontend

Stores covering auth, quotes, playlists, payments, slideshow settings, notifications, API keys, and more.

Why: Vue 3's official store. Composition-API style keeps store logic testable and co-located, and TypeScript inference requires no extra typing wiring.

VueUse

Frontend

Composable utilities — localStorage sync, intersection observer, debounce, media queries, clipboard access, and event listeners.

Why: Avoids reimplementing browser-API wrappers that VueUse already handles correctly, including SSR safety.

AI Features

OpenAI

Backend

Quote explanations, category auto-detection, grammar corrections, text-to-speech generation, and content moderation.

Why: API keys never reach the browser — all calls are made server-side with appropriate rate limiting.

Payments

Mollie

Backend

Subscription billing across three tiers (Free / Hobby / Supporter) and one-time credit purchases.

Why: EU-first payment provider with iDEAL and Bancontact support — essential for a Dutch-hosted product. Webhook signatures are verified server-side before touching any billing state.

Email

Resend

Backend

Transactional emails — account notifications, changelog digests, and subscription receipts.

Why: Simple REST API with reliable deliverability and good developer tooling.

Animations & Effects

GSAP

Frontend

Sequenced animations — page transitions, stagger list reveals, and the preloader sequence.

Why: Timeline API gives precise control over multi-step sequences that CSS transitions alone cannot express cleanly.

Motion-V

Frontend

Vue-idiomatic scroll-triggered reveals and layout animations.

Why: Declarative component and directive API fits into Vue templates without imperative lifecycle hooks.

OGL

Frontend

WebGL background effects — the Silk and Aurora animated backgrounds.

Why: Minimal WebGL abstraction (~10 KB) — enough power for shader-based visuals without the weight of Three.js.

Monitoring & Analytics

Umami

Frontend

Page views, custom events (preset applied, quote liked, playlist created), and session analytics.

Why: Cookie-free and GDPR-compliant by default — no consent banner required, no PII collected.

Bugsink / Sentry

Frontend

Captures and groups runtime errors from production users with stack traces and breadcrumbs.

Why: Surfaces JS errors that would otherwise be invisible post-deployment — with stack traces, breadcrumbs, and user context.

Testing

Vitest + happy-dom

Frontend

Unit tests for utilities, store logic, and composables.

Why: Runs inside the same Vite pipeline as Nuxt — no separate Jest config, faster cold starts, and native ESM support without transform workarounds.

Rich Text & Forms

TipTap

Frontend

Rich-text editor for author descriptions and quote editing in the admin panel.

Why: Headless ProseMirror wrapper with Vue 3 support and a clean extension API for custom marks, nodes, and slash commands.

vee-validate

Frontend

Form validation for auth flows, submission forms, and account settings.

Why: Integrates with shadcn-vue form components out of the box. Schema-based validation keeps rules co-located with types.

Data & Charts

Unovis

Frontend (admin dashboard)

Charts for admin analytics — quote view trends, user signups, and error rates over time.

Why: Framework-agnostic core with a thin Vue wrapper; good TypeScript support without pulling in a heavyweight BI library.

@tanstack/vue-table

Frontend (admin panel)

Data tables with sorting, filtering, and pagination for quotes, users, and moderation queues.

Why: Headless table logic — the library handles complex state while rendering stays entirely in Vue templates.