QED Website - A Scientific Dissemination Platform
Project Overview
The QED website is a full-stack web application built for the QED mathematical association at Universidad Autónoma de Madrid. The platform serves as both an organizational hub and an educational resource, with a primary focus on making mathematics accessible and engaging for audiences from high school level and above. Through an interactive digital magazine, the site presents complex mathematical concepts, recent discoveries, and intriguing problems in an approachable, entertaining format.
Technical Stack
Backend
- Runtime: Node.js with TypeScript
- Framework: Express.js for routing and middleware
- Database: MongoDB with Mongoose ODM
- Authentication: Passport.js with Google OAuth2 strategy
- Templating: EJS (Embedded JavaScript) for server-side rendering
- Email: Brevo API for transactional emails
- Security: CSRF protection, helmet middleware, cookie sessions
Frontend
- Styling: Tailwind CSS with custom utilities and dark mode support
- 3D Graphics: Three.js for animated particle systems on the homepage
- Math Rendering: KaTeX for LaTeX equation rendering
- Markdown Processing: Custom markdown-it pipeline with extensive plugins
- Progressive Web App: Service worker with offline fallback pages
- Internationalization: i18n with route translation support
Development Tools
- Build System: Native TypeScript compilation, PostCSS, Tailwind CLI
- Development: Nodemon for hot reloading
- Code Quality: ESLint, Prettier
- Deployment: Docker containerization with multi-stage builds
Architecture Highlights
Multilingual Routing System
The site implements a sophisticated internationalization system that goes beyond simple text translation. Routes themselves are translated - for example, /revista/articulo/[post] in Spanish becomes /magazine/post/[post] in English. This is achieved through:
- A
getRouteTranslationsutility that generates localized route patterns - Middleware that parses the user’s preferred locale
- Dynamic content selection using MongoDB aggregation pipelines with
$ifNullfallback chains - Translation files loaded per request to serve the correct language
Example from magazine.ts:
router.get(getRouteTranslations("magazine.post", ":post"), async (req, res) => {
const lang = req.getLocale();
const post = await Post.aggregate([
{ $match: { url: req.params.post } },
{
$addFields: {
selectedTitle: { $ifNull: [`$title.${lang}`, `$title.es`] }
}
}
]);
...
});
Custom Markdown Processing Pipeline
Articles are written in Markdown but require mathematical notation, interactive elements, and semantic containers. The mdParser.ts implements a custom pipeline:
- Math Support: KaTeX integration for inline (
$...$) and display ($$...$$) equations - Custom Containers: Markdown-it-container extensions for:
- Spoiler sections with click-to-reveal overlays
- Solution blocks with dashed borders
- Interactive JavaScript element placeholders
- Theorem/proof/question semantic blocks
- Syntax Highlighting: Automatic code highlighting with language detection
- Embedded Media: Block-embed plugin for YouTube, Vimeo, and other services
- Advanced Tables: Multi-line cells, rowspan, headerless tables via markdown-it-multimd-table
- Footnotes & Abbreviations: Academic writing support
The pipeline preprocesses raw Markdown (handling special syntax), renders through markdown-it with plugins, then postprocesses HTML to inject interactive element scripts.
Interactive Element Framework
A custom JavaScript framework (postInteractiveElements.js) enables embedding mathematical simulations, visualizations, and games directly in articles. The system features:
- Lifecycle Management: Start, pause, resume, reset, and stop controls
- State Persistence: LocalStorage integration for saving puzzle progress
- Performance: Viewport-aware execution that pauses off-screen elements
- Responsive Design: Automatic canvas/SVG resizing and mobile touch support
- Accessibility: Keyboard navigation for puzzles, semantic HTML, theme integration
Interactive elements are defined using custom Markdown containers:
::: js ElementClassName
[param1, param2]
uniqueInstanceName
autoPlay,allowPause,saveStates
:::
See the Interactive Components System for detailed technical documentation.
Progressive Web App Features
The site implements a service worker (sw.js) with intelligent offline handling:
- Offline Pages: Custom error pages for “no internet” vs “server down” scenarios
- Language-Aware Fallbacks: Serves offline pages in the user’s preferred language
- Timeout Detection: Distinguishes between network issues and slow responses
- Cache Strategy: Precaches critical assets while falling back to network for content
The service worker implements a race condition between a 1-second timeout and the actual network request, providing fast feedback when connectivity issues occur.
Theme System
Dark mode is implemented as a first-class citizen, not an afterthought:
- SSR Detection: Server-side script (theme.js) checks localStorage before page render to prevent flash of wrong theme
- Tailwind Integration: Dark variant classes throughout the codebase
- Dynamic Scrollbar: CSS custom properties update scrollbar colors instantly on theme change
- Third-Party Integration: Even offline pages (served via service worker) respect theme preference
- SVG Inversion: Logo and icon colors adapt via CSS filters
The theme script runs before any visual rendering, preventing the common “white flash” issue on dark mode sites.
Database Schema Design
MongoDB schemas (models) use flexible structures to support multilingual content:
const postSchema = new Schema({
url: { type: String, required: true, unique: true },
title: { type: Map, of: String, default: { es: "" } },
description: { type: Map, of: String, default: { es: "" } },
content: { type: Map, of: String, default: { es: "" } },
tags: { type: [String], default: [] },
authors: [
{
user_id: { type: Schema.Types.ObjectId, ref: "User" },
role: String
}
],
magazine_id: { type: Schema.Types.ObjectId, ref: "Magazine" },
views: { type: Number, default: 0 }
});
Maps allow storing translations without rigid schema changes. Aggregation pipelines select the appropriate language field at query time.
Admin Content Management
The admin panel (admin) provides a complete CMS:
- Live Markdown Preview: Real-time rendering as editors type, using the same pipeline as production
- Interactive Element Testing: Admins can test interactive components before publishing
- Multi-Language Editing: Side-by-side editors with preview tabs for each supported language
- CSRF Protection: Token-based form security on all mutations
- Validation: URL patterns, required fields, and type checking with user-friendly error messages
- Asset Management: Magazine cover uploads, user profile images with fallbacks
Preview updates are asynchronous POST requests to /admin/mdParse, rendering Markdown server-side and returning HTML via JSON. This ensures the preview matches production output exactly.
Three.js Homepage Animation
The landing page features a custom particle system (index.ejs) built with Three.js:
- Vertex Shaders: GPU-accelerated particle rendering with custom scaling
- Fragment Shaders: Dynamic color gradients that transition smoothly on theme change
- Wave Animation: Mathematical sine function creates a rippling surface effect
- Responsive: Particle count and size adapt to viewport dimensions
- Performance: Runs at 60 FPS on modern devices by limiting particle count and using efficient shaders
- Theme Integration: Colors fade between light/dark palettes using
vec3interpolation
The animation provides visual interest without distracting from content, and the canvas is positioned absolutely behind text content.
Authentication & Authorization
User authentication uses Passport.js with Google OAuth:
- Session Management: Encrypted cookies with key rotation support
- Role-Based Access: User roles (admin, member, collaborator) control access to CMS features
- Directive Board: Tracks historical board positions by academic year
- Profile System: Public user profiles with markdown-rendered bios and publication lists
The user.ts aggregates a user’s contributed articles across magazines, handling multilingual titles and filtering by magazine visibility.
Performance Optimizations
Database Queries
- Aggregation Pipelines: Complex queries execute in a single round trip
- Selective Fields:
$projectstages limit transferred data - Lean Queries:
.lean()returns plain objects instead of Mongoose documents for read-only operations
Frontend
- Deferred Scripts: Non-critical JS loads with
deferattribute - CSS Purging: Tailwind removes unused classes in production
- SVG Sprites: Icons reuse paths rather than embedding multiple copies
- Lazy Loading: Images and interactive elements load on demand
Caching
- Static Assets: Public folder served with efficient caching headers
- Service Worker: Offline-first approach for critical resources
- Browser Hints: DNS prefetch, preconnect for external resources
SEO & Metadata
Pages include comprehensive meta tags:
- Open Graph for social media previews
- Twitter Card support
- Schema.org structured data for articles (JSON-LD)
- Canonical URLs
- Sitemap generation (implied by routing structure)