How This Site Was Built

A comprehensive overview of the technology stack, architecture, and design decisions behind Less Likely.
Author
Published

May 24, 2026

Last updated

September 14, 2026

Overview

Less Likely is a modern static website built with Quarto, designed specifically for academic and scientific content with a focus on statistical methodology. This page documents the complete technology stack, architectural decisions, and evolution of the site.

Architecture Diagram

Technology Stack

Core Infrastructure

Quarto Publishing System

  • - Next-generation scientific publishing system
  • Version: 1.9+
  • Why Quarto?
    • Native support for R, Python, Julia, and Observable
    • Superior mathematical typesetting with KaTeX
    • Built-in citation management
    • Cross-reference capabilities
    • Code execution and visualization
    • Professional academic output

Content Creation

  • RMarkdown/Quarto Markdown - Primary authoring format
  • RStudio/VS Code - Integrated development environments
  • R Packages:
    • Core statistical computing
    • Data visualization (ggplot2)
    • Tables (knitr, kableExtra)
    • Special packages for specific analyses

Version Control & Deployment

  • Git/GitHub - Version control and source hosting
  • Netlify - Hosting, CDN, and deploy pipeline
    • Automatic deployment on git push to master
    • Netlify does not render the site. The site is rendered locally and _site/ (plus the _freeze/ computation cache) is committed. Netlify’s build step only builds the CMS admin app (cd cms && npm ci && npm run build), then publishes the committed _site/. A content change is not live until it is re-rendered and committed.
    • CSS/JS bundling and minification
    • Custom HTTP headers and CSP
    • Redirect rules for canonical URLs
    • Build plugins: @netlify/plugin-lighthouse, netlify-plugin-submit-sitemap, netlify-plugin-formspree, and @algolia/netlify-plugin-crawler (disabled)
    • Netlify Functions - serverless endpoints in netlify/functions/ (site status, Disqus webhook, CMS auth, PageSpeed proxy, an ai prompt endpoint routed through Netlify AI Gateway, and the UFC dashboard backend). Public /api/* paths are declared in each function’s own config.path export, not via rewrites in netlify.toml – except ufc.mjs, which still uses the legacy handler export with no config.path and is therefore only reachable at /.netlify/functions/ufc now that its /api/* rewrites were removed from netlify.toml

Third-Party Services

Search & Discovery

  • Algolia - Full-text search with hosted index
    • Index name quarto, app ID configured in _quarto.yml
    • @algolia/netlify-plugin-crawler is installed but currently disabled = true in netlify.toml; index is maintained manually
    • Instant results with keyboard shortcuts (f, /, s)
    • Category filtering
    • Custom icons for result types (injected by search-images.js)
  • Algolia Agent Studio - Conversational search/chat widget, loaded site-wide via scripts/agent-chat-loader.html

Typography & Fonts

  • Google Fonts - Web typography
    • Source Serif Pro - Body text (serif)
    • IBM Plex Mono - Code snippets (monospace)
  • Font loading: Preconnect to fonts.googleapis.com and fonts.gstatic.com for performance

Mathematics & Scientific Notation

  • KaTeX - Mathematical rendering (html-math-method: katex in _quarto.yml)
    • LaTeX syntax support
    • Inline and display math
    • Faster client-side rendering than MathJax (which the site used previously)

Quarto Extensions

Active extensions installed under _extensions/:

  • quarto-ext/fontawesome - FontAwesome icon embedding in prose
  • quarto-ext/fancy-text - Styled text effects
  • quarto-ext/attribution - Content attribution blocks
  • quarto-ext/include-code-files - Import external code files into code blocks
  • mcanouil/iconify - Iconify icon set integration
  • mikemahoney218/arxiv - arXiv citation and link helpers
  • r-wasm/live - WebR live code execution in the browser
  • shafayetShafee/bsicons - Bootstrap icon set
  • shafayetShafee/collapse-callout - Collapsible callout blocks
  • fradav/animate - Animate.css effects via the animate filter
  • mcanouil/highlight-text - Inline text highlighting via the highlight-text filter
  • leovan/pseudocode - Pseudocode rendering via the pseudocode filter
  • quarto-journals/elsevier - Elsevier journal article format (installed for manuscript output; not a site filter)
  • shafayetShafee/downloadthis - Download-button shortcode (installed; not a site-wide filter)

Note: Lightbox image gallery (lightbox: auto) is a Quarto built-in feature since v1.4. The quarto-ext/lightbox extension is also installed under _extensions/ (for per-document override use).

Reference Management

  • Zotero - Bibliography and citation management
  • CSL - Citation Style Language for formatting
  • BibTeX - Bibliography format
  • Integration:
    • Automatic citation insertion
    • Site-wide bibliography declared in _quarto.yml as references-cited.bib + packages.bib, formatted with custom.csl; posts may add their own files on top
    • references-cited.bib (and the statistics/, nutrition/ equivalents) is generated, not edited: scripts/slim-bibs.py (pre-render) extracts only the cited entries from the 2.6–3.6 MB Zotero exports (references.bib etc.) so citeproc stops parsing multi-megabyte BibTeX on every page. --verify checks that every key resolves against the slim file iff it resolves against the source
    • Citation hover cards show the paper’s abstract: scripts/inject-abstracts.py (post-render) appends a collapsed <details> to each reference entry from the .bib abstract field or scripts/abstracts-cache.json, which scripts/fetch-abstracts.py fills on demand from OpenAlex (not part of the render, so builds never depend on a third-party API)
    • Hover previews for citations (citations-hover: true)

Image Optimization

  • Cloudinary - Image CDN and optimization
    • Automatic format conversion (WebP)
    • Responsive images
    • Lazy loading
    • Compression and optimization

Analytics & Monitoring

  • Google Analytics 4 (G-9WVCJ5ZY42) - Traffic and event tracking
    • Loaded via gtag.js in include-in-header.html
    • Cookie consent (type: implied) wired through Quarto
  • Microsoft Clarity (kjbivoumgn) - Session recordings and heatmaps, loaded via include-in-header.html
  • Google Search Console - SEO monitoring
  • Bing Webmaster Tools - Additional search insights

Social Features

  • Disqus - Comments, loaded via scripts/disqus-loader.html; threads are keyed to legacy post URLs (see redirect rules in netlify.toml)
  • Webmentions - Received via (rel="webmention"/rel="pingback" endpoints declared once in include-in-header.html); rendered on post pages by js/webmention.js, loaded from scripts/webmentions-loader.html after the target container exists (a second, older copy at /webmention.js is also loaded async from include-in-header.html, so both currently ship)
  • Twitter Cards - Rich social media previews
  • Open Graph - Social sharing optimization
  • Altmetric - Attention badges for cited papers, via the embed script loaded site-wide in include-in-header.html

Site Architecture

Frontend Design

Styling System

  • Bootstrap 5 - Base CSS framework (via Quarto/Bootswatch)
  • Custom SCSS - Theme customization
    • Light theme: Paper (Bootswatch) + theme-mono.scss overrides
    • Dark theme: standalone theme-dark.scss (no Bootswatch parent)
    • Custom color variables
    • Brand colors: #4895ab (primary), #d46c5b (accent)

Layout Components

  • Responsive Navigation - Mobile-friendly navbar
  • Sidebar Navigation - Contextual links
  • Table of Contents - Automatic generation
  • Code Blocks - Syntax highlighting with language badges
  • Copy Buttons - One-click code copying
  • Search Results - Custom icons and styling

Custom Features

  1. Language Badges - Visual code block identifiers
  2. Copy Code Functionality - Enhanced clipboard integration
  3. Search Icons - Category-specific visual indicators
  4. Image Centering - Consistent image display
  5. Table Styling - Professional data presentation
  6. Theme Toggle - Three-state light/dark/flux switcher (js/theme-toggle.js); flux is a Night Shift-style warm-tone mode (css/flux-mode.css)
  7. R Function Documentation Links - R function calls in code blocks link to , with hover previews showing the function’s help title and description (js/rdoc-links.js).
    • scripts/generate-rdoc-map.R (pre-render) resolves each function used on the site to its package and Rd topic from the locally installed help indices, since RDocumentation keys pages by Rd file name rather than alias (sapply() lives at base/topics/lapply).
    • Preview text ships in rdoc-map.json, so hovering costs no third-party request; the map is fetched only on pages that contain R code.
    • scripts/verify-rdoc-map.py checks every generated URL, repairs topics upstream has renamed, and prunes any that cannot be resolved, so no reader hits a dead documentation link. Run it after adding posts that use new packages.
  8. Stata Command Documentation Links - Stata commands in code blocks link to their help page, with hover previews built from the command’s own help text (js/stata-links.js).
    • scripts/generate-stata-map.R (pre-render) scans Stata fences for command-position tokens (handling /// line-continuations and qui/cap/svy/bayes-style prefixes so trailing words on a continued line, e.g. as in display ... as text ///, are never mistaken for a new command) and resolves each against the locally installed .sthlp files (/Applications/StataNow/ado/base/**), including abbreviation matching (gen -> generate) at any length Stata itself accepts, not just the documented minimum.
    • Preview text (section + description) is parsed straight out of each command’s SMCL help file and ships in stata-map.json, so hovering costs no third-party request.
  9. Python Call Documentation Links - Python function/method calls in code blocks link to the official docs for numpy, pandas, scipy, statsmodels, matplotlib, scikit-learn, and the standard library, with hover previews built from the callable’s own docstring (js/python-links.js).
    • scripts/generate-python-map.py (pre-render hook currently commented out in _quarto.yml, so python-map.json is refreshed manually; run with the pyenv interpreter that has every relevant package installed, not the python3 on PATH) parses each Python fence with ast (not regex) to resolve import aliases and enumerate real Call nodes, then resolves each call two ways: first the alias-resolved literal path against the matching package’s Sphinx objects.inv inventory, falling back to the locally installed package’s runtime-introspected __module__.__qualname__ when a package only documents its internal path (e.g. sm.OLS -> statsmodels.regression.linear_model.OLS).
    • Inventories are fetched over the network and cached in scripts/python-inv-cache.json (refreshed if older than 30 days, or reused stale if the fetch fails), so a render doesn’t need network access every time.
    • Preview text is the callable’s own docstring first line, captured at build time and shipped in python-map.json, so hovering costs no third-party request.
  10. Gwern-style Reading Features (added September 2026; css/design-features.css, js/design-features.js) - every enhancement degrades to plain HTML.
    • Sidenotes - footnotes render in the margin on wide screens and inline below ~992px (reference-location: margin in _quarto.yml; no JS).
    • Link popups - hover previews for Wikipedia (REST summary), arXiv (export API abstract), and internal links (first paragraph of the target article); other links get a destination card from local metadata, so no URL is sent to a third-party preview service (js/link-popups.js, tippy.js, 7-day localStorage cache).
    • Abstract previews - citation hover cards include the paper’s abstract (see Reference Management above).
    • Backlinks with context - scripts/backlinks.py (post-render) appends a Backlinks section to each post listing every internal page that links to it, the passage containing the link, and a deep link to the source section. One-way and rebuilt on each render, not Gwern’s live bidirectional graph.
    • Sortable tables - click a <th> to sort (numeric- and locale-aware); tables marked .no-sort are left alone.

Content Organization

my-quarto-site/
├── _quarto.yml              # Site configuration
├── index.qmd                # Homepage
├── about.qmd                # About page
├── blog.qmd                 # Blog listing
├── posts.qmd                # Alternative post view
├── projects.qmd             # Projects showcase
├── dashboards.qmd           # Interactive dashboards
├── glossary.qmd             # Terminology reference
├── sitemap.qmd              # Human-readable site map
├── contact.qmd              # Contact information
├── support.qmd              # Support page
├── blogroll.qmd            # Links to other sites
├── datasets.qmd            # Data repositories
├── privacy.qmd              # Privacy policy
├── license.qmd              # Licensing terms
├── conduct.qmd              # Comment policy
├── 404.qmd                  # Custom error page
├── build.qmd                # This page!
│
├── statistics/             # Statistical methodology posts
├── medicine/               # Medical research posts
├── nutrition/              # Nutritional science posts
│
├── images/                  # Site images and assets
├── styles/                  # Custom CSS
└── _site/                   # Generated output

Metadata & SEO

Head Tags

include-in-header.html was trimmed in September 2026 to only what Quarto does not already emit (about two dozen <meta> tags, down from ~80). Quarto itself generates the charset, viewport, canonical, Open Graph, and Twitter Card tags from _quarto.yml.

  • Basic SEO: Title, description, keywords, author, robots snippet/preview controls
  • Open Graph: Facebook, LinkedIn sharing (og:locale, og:type, og:site_name, fb:app_id in the header; the rest from _quarto.yml)
  • Twitter Cards: Rich Twitter previews (summary_large_image)
  • Academic: Google Scholar citation_* tags are currently off (google-scholar: false in _quarto.yml); the hand-written citation_* and Dublin Core tags were removed from the header. Per-post academic metadata now lives in the injected JSON-LD only
  • Structured Data: JSON-LD schemas
  • Mobile: iOS, Android optimization
  • Verification: Google, Bing, Yandex
  • Discovery: opensearch.xml (browser address-bar search), IndexNow verification key for Bing/Yandex push indexing
  • AI visibility: llms.txt site index generated by Quarto (llms-txt: true), plus per-post .llms.md companions

Schema.org Structured Data

  • WebSite schema with site search (include-in-header.html, site-wide)
  • Person schema (author; worksFor names Less Likely inline – the standalone Organization schema was removed)
  • BlogPosting schema (articles; injected per post by scripts/inject-article-jsonld.py post-render)

Content Workflow

Writing Process

  1. Create New Post

    # Create new .qmd file in statistics/ (or medicine/, nutrition/)
    touch statistics/new-post.qmd
  2. Write Content

    • Use RMarkdown syntax
    • Execute R code inline
    • Create visualizations
    • Add citations with
    • Include mathematical notation
  3. Preview Locally

    quarto preview
  4. Build Site

    quarto render
  5. Deploy

    # Commit the source AND the rendered output -- Netlify does not render.
    git add . _site _freeze
    git commit -m "Add new post"
    git push
    # Netlify publishes the committed _site/ on push to master

Post Template

---
title: "Your Post Title"
author:
  - name: Sir Panda
    orcid: "0000-0003-1545-8199"
date: "2025-01-08"
categories: [statistics, methodology]
description: "Brief description of your post"
image: "featured-image.png"
citation:
  type: article
  container-title: "Less Likely"
  url: https://lesslikely.com/statistics/your-post
bibliography: references.bib
---

## Introduction

Your content here...

Historical Evolution

Verified against snapshots spanning 2011–2026.

WordPress Era (~2011–early 2019)

  • Platform: WordPress 4.x → 5.0.2 on SiteGround hosting (WP 4.9.5 confirmed May 2018; WP 5.0.2 confirmed Dec 2018)
  • Theme: GeneratePress Premium
  • Key plugins: WP Rocket (caching), Imagify (image optimization), Yoast SEO
  • Challenges:
    • Plugin dependency and update fatigue (core + theme + plugins all diverge)
    • Database vulnerabilities and security patching overhead
    • Poor LaTeX rendering performance
    • High maintenance burden for a static-content site

Hugo Era (~early 2019–early 2026)

The longest single era: Hugo 0.55.4 (first confirmed Jun 2019) through Hugo 0.134.2 (last confirmed Feb 2026) — roughly seven years on a continuously upgraded Hugo binary.

  • Platform: Hugo static site generator (v0.55 → v0.134)
  • Theme: Custom Bootstrap-based theme with particle.js homepage effects; no off-the-shelf theme
  • Math: KaTeX; MathJax added alongside it in later years (both loaded by ~2024)
  • Fonts: Adobe Typekit (kit gyq1osp) at launch; switched to Google Fonts around 2022 — Merriweather, Lato, Roboto, Inconsolata, Fira Code
  • Search: Algolia InstantSearch (early), later Algolia Autocomplete + Netlify crawler frontend
  • Analytics: Google Analytics Universal (UA) in early Hugo era
  • Community: Discourse forum (discourse.lesslikely.com) linked from navbar in early years; later removed
  • Tagline: “Separating Signals From Noise” (changed to current subtitle during Quarto migration)
  • Improvements over WordPress:
    • Eliminated database and plugin attack surface
    • Fast static HTML — sub-second load times
    • Full control over math rendering and code display
    • No hosting fees beyond Netlify free tier

Quarto Era (~early 2026–present)

Wayback Machine first confirms Quarto on 30 Apr 2026 (generator tag: quarto-1.8.27). The Hugo generator tag was already absent in the Feb 2026 snapshot, suggesting the migration happened in late Feb–Mar 2026.

  • Platform: Quarto publishing system (v1.8 → 1.9+)
  • Why the switch from Hugo?
    • Native R/Python/Julia code execution and freeze caching
    • Built-in citation management, hover previews, cross-references
    • Academic metadata (per-post JSON-LD BlogPosting; Google Scholar citation_* tags available via google-scholar, currently switched off)
    • llms.txt and AI-visibility features built into the toolchain
    • Algolia integration carried over; all prior Algolia search config reused
    • Active Posit/RStudio community vs. Hugo’s Go-centric ecosystem

Key Benefits of Quarto: No plugin dependencies — superior mathematical typesetting — native academic features — cross-platform R/Python/Julia support — active development — future-proof for scientific publishing.

Design Philosophy

Principles

  1. Content First
    • Clean, readable typography
    • Minimal distractions
    • Focus on the writing
  2. Academic Rigor
    • Proper citations
    • Mathematical precision
    • Code reproducibility
    • Data transparency
  3. Performance
    • Static generation
    • CDN delivery
    • Image optimization
    • Minimal JavaScript
  4. Accessibility
    • Semantic HTML
    • ARIA labels
    • Keyboard navigation
    • Screen reader support
  5. Responsive Design
    • Mobile-first approach
    • Flexible layouts
    • Touch-friendly interfaces
    • Readable on all devices

Color Scheme

Brand Colors: - Primary: #4895ab (Teal blue) - Accent: #d46c5b (Coral red) - Neutral: #343a40 (Dark gray) - Light: #f8f9fa (Off white)

Dark Mode: - Background: #2d2d2d - Text: #e0e0e0 - Links: #5aa9bd - Borders: #404040

Performance Optimizations

Build Time

  • Freeze feature for code execution
  • Incremental builds
  • Cached computations
  • Parallel processing
  • Skippable render hooks: every pre/post-render script in _quarto.yml runs through scripts/run-render-hook.sh, which exits early when LL_FAST_RENDER=1 or the dev Quarto profile is active. slim-bibs.py is the deliberate exception (it is a no-op when fresh, and a dev render must not see stale bibs)

Runtime

  • Static HTML (no server processing)
  • CDN distribution (Netlify Edge)
  • Font subsetting
  • Image lazy loading
  • Code splitting

Metrics

  • Lighthouse scores: 95+ across categories
  • First Contentful Paint: < 1s
  • Time to Interactive: < 2s
  • Total Blocking Time: < 100ms

Future Enhancements

Planned Features

Technical Improvements

Content Additions

Development Setup

Requirements

  • R (4.6+)
  • RStudio or VS Code
  • Quarto (1.9+)
  • Git
  • Node.js (for extensions)

Installation

# Install Quarto
# Download from https://quarto.org/docs/get-started/

# Clone repository
git clone https://github.com/zadrafi/lesslikely.git
cd lesslikely/my-quarto-site

# Install R packages
Rscript -e "install.packages(c('knitr', 'rmarkdown', 'ggplot2'))"

# Preview site
quarto preview

# Build site
quarto render

Configuration Files

**_quarto.yml** - Main configuration - Project settings - Website metadata - Navigation structure - Format options - Extensions

styles.css - Custom styling - Brand colors - Component styles - Dark mode - Responsive design

include-in-header.html - Head content - Metadata tags - Analytics scripts - Font loading - Structured data

Lessons Learned

What Worked Well

  1. Static Generation - Fast, secure, reliable
  2. Version Control - Complete history and rollback
  3. Quarto - Excellent for academic content
  4. CDN Hosting - Global performance
  5. Custom Theme - Full design control

Challenges Overcome

  1. Migration - Moving from Hugo to Quarto
  2. Dark Mode - Consistent styling across themes
  3. Search - Implementing custom icons
  4. Citations - Managing multiple bibliographies
  5. Performance - Optimizing large R computations

Best Practices

  1. Always preview changes locally
  2. Use meaningful commit messages
  3. Keep dependencies minimal
  4. Document custom features
  5. Test on multiple devices
  6. Monitor analytics regularly
  7. Maintain backup copies

Resources & Credits

Tools & Technologies

Design Inspiration

Community

Contact & Feedback

Have questions about the site architecture? Want to implement something similar?

Open Source

While the content is copyrighted, the site’s technical implementation can serve as a reference for building academic websites with Quarto.

Key Takeaway: A well-designed static site with Quarto can deliver excellent performance, maintainability, and user experience for academic and scientific content without the complexity and overhead of dynamic CMS platforms.


Last updated: September 14, 2026

This page itself is built with Quarto, demonstrating the capabilities we describe!

Back to top