Skip to content

Mobile-first Bitcoin & sound-money knowledge base with analytics and experimentation via PostHog.

Notifications You must be signed in to change notification settings

jorisstrakeljahn/thereforbitcoin

Repository files navigation

Therefor Bitcoin

Mobile-first Bitcoin knowledge base frontend (Next.js + MDX) with a premium editorial design.

A comprehensive, balanced knowledge base helping people understand Bitcoin through well-researched, fair content. Clear answers, fair objections, and primary sources.

License Next.js TypeScript

🎯 Project Vision

A premium, modern "linkable in conversations" Q&A wiki where users land on a specific question page and get a clear answer fast. Optimized for "user finds a useful answer in < 30 seconds."

Design Principles

  • Premium editorial vibe: Generous whitespace, strong typography, high contrast
  • Mobile-first: Big tap targets, sticky navigation, search-first UX
  • Dark mode built-in: Not an afterthought
  • Trust cues: Sources, last updated dates, balanced perspectives
  • One accent color: Bitcoin orange (#F7931A)

πŸš€ Quick Start

Prerequisites

  • Node.js 18+
  • pnpm (recommended) or npm

Installation

# Clone the repository
git clone https://github.com/jorisstrakeljahn/thereforbitcoin.git
cd thereforbitcoin

# Install dependencies
pnpm install

# Start development server
pnpm dev

Open http://localhost:3000 to see the app.

πŸ“ Project Structure

thereforbitcoin/
β”œβ”€β”€ content/                 # MDX content files
β”‚   └── en/                  # English content
β”‚       β”œβ”€β”€ beginner/        # Beginner-level articles
β”‚       β”œβ”€β”€ criticism/       # Criticism articles
β”‚       β”œβ”€β”€ lightning/       # Lightning Network articles
β”‚       β”œβ”€β”€ mining/          # Mining articles
β”‚       └── money/           # Sound money articles
β”œβ”€β”€ public/                  # Static assets (clean - no default files)
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ app/                 # Next.js App Router pages
β”‚   β”‚   β”œβ”€β”€ api/             # API routes
β”‚   β”‚   β”œβ”€β”€ articles/        # Article pages
β”‚   β”‚   β”œβ”€β”€ glossary/        # Glossary page
β”‚   β”‚   β”œβ”€β”€ paths/           # Learning paths page
β”‚   β”‚   β”œβ”€β”€ search/          # Search page
β”‚   β”‚   β”œβ”€β”€ sources/         # Sources library page
β”‚   β”‚   └── topics/          # Topic pages
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ article/         # Article-specific components
β”‚   β”‚   β”œβ”€β”€ icons/           # Lucide-style SVG icon components
β”‚   β”‚   β”œβ”€β”€ layout/          # Header, Footer
β”‚   β”‚   β”œβ”€β”€ mdx/             # MDX components (TLDRBox, etc.)
β”‚   β”‚   β”œβ”€β”€ search/          # Search modal
β”‚   β”‚   └── ui/              # UI primitives
β”‚   β”œβ”€β”€ lib/
β”‚   β”‚   β”œβ”€β”€ content/         # Content loader & schema
β”‚   β”‚   β”œβ”€β”€ hooks/           # React hooks
β”‚   β”‚   └── search/          # Search functionality
β”‚   └── styles/              # Global CSS & tokens
└── ...config files

πŸ“ Content System

Content is stored as MDX files in the content/ directory with Zod-validated frontmatter.

Frontmatter Schema

---
slug: what-is-bitcoin
title: What is Bitcoin?
summary: A digital currency without banks... (max 300 chars)
tags: [basics, introduction]
topic: basics # basics, security, mining, lightning, economics, criticism, money, dev
level: beginner # beginner, intermediate, advanced
type: qa # qa, explainer, criticism, glossary, source
language: en
lastUpdated: "2024-01-15"
tldr: # Max 5 bullet points
  - Point one
  - Point two
whyPeopleAsk: Why users search for this
whatIsTrue: [verified facts]
whatIsUncertain: [debated points]
sources:
  - title: Source Name
    url: https://example.com
    author: Author Name
    type: primary # primary, secondary, video, book, article, podcast
---

Adding New Content

  1. Create a new .mdx file in the appropriate content/en/[category]/ folder
  2. Add the required frontmatter
  3. Write your content using markdown + MDX components
  4. The article will automatically appear in the relevant topic page

MDX Components

  • <TLDRBox items={[...]} /> - Bullet-point summary box
  • <Callout type="info|warning|success|error|tip">...</Callout>
  • <SourcesList sources={[...]} />
  • <KeyTakeaways items={[...]} />
  • <InlineTerm term="satoshi">satoshis</InlineTerm> - Glossary popover

🎨 Icon System

Uses a custom Lucide-style SVG icon system located in src/components/icons/.

Available Icons

import { 
  // Navigation
  Menu, X, Search, Sun, Moon, ChevronRight, ChevronDown, ArrowLeft, ArrowRight,
  
  // Topics
  Bitcoin, Shield, Lock, Pickaxe, Zap, TrendingUp, HelpCircle, Coins, Code,
  
  // Content
  BookOpen, FileText, Video, Headphones, Library, GraduationCap,
  
  // Actions
  Check, Copy, ExternalLink, Share, Info, AlertCircle, AlertTriangle,
  
  // Misc
  Clock, Calendar, List, Hash, Tag, Sparkles, Scale, Quote
} from '@/components/icons';

Usage

import { Bitcoin, Search } from '@/components/icons';

// Basic usage
<Bitcoin size={24} />

// Custom props
<Search size={18} strokeWidth={2.5} className={styles.icon} />

TopicIcon Component

For topic-specific icons:

import { TopicIcon } from '@/components/icons';

<TopicIcon topic="lightning" size={20} />

🎨 Styling System

Uses plain CSS with CSS Modules and CSS custom properties (no Tailwind).

Design Tokens

Located in src/styles/tokens.css:

  • Colors (with dark mode variants)
  • Typography scale
  • Spacing scale
  • Border radii
  • Shadows
  • Transitions
  • Z-index scale

Dark Mode

Supports:

  • System preference detection (prefers-color-scheme)
  • Manual toggle (persisted to localStorage)
  • [data-theme="dark"] attribute on <html>

Reduced Motion

Respects prefers-reduced-motion media query.

πŸ” Search

Local search implementation using frontmatter + content indexing.

  • Searches titles, summaries, and tags
  • Supports filtering by topic, type, and level
  • Keyboard navigation (⌘K to open, arrows to navigate)
  • Highlighting of matched terms

πŸ“± Responsive Design

  • Mobile-first CSS
  • Breakpoints: 640px, 768px, 1024px, 1280px
  • Collapsible navigation on mobile
  • Sticky mobile navigation button for article TOC

πŸ” SEO

  • Per-page metadata & Open Graph tags
  • Dynamic sitemap (/sitemap.xml)
  • Robots.txt (/robots.txt)
  • Semantic HTML structure
  • Clean, human-readable URLs

πŸ§ͺ Development

# Development server
pnpm dev

# Type checking
pnpm type-check

# Linting
pnpm lint

# Build for production
pnpm build

# Start production server
pnpm start

πŸ§ͺ Testing

The project uses a comprehensive test suite with BDD-style E2E tests and unit tests.

Test Stack

Running Tests

# Run all tests (unit + E2E)
pnpm test

# Run unit tests only
pnpm test:unit

# Run unit tests in watch mode
pnpm test:unit:watch

# Run E2E tests (headless) - Desktop + Mobile
pnpm test:e2e

# Run only Desktop tests
pnpm exec playwright test --project=chromium

# Run only Mobile tests
pnpm exec playwright test --project=mobile

# Run E2E tests with browser UI
pnpm test:e2e:headed

# Run E2E tests with Playwright UI
pnpm test:e2e:ui

Test Projects

Project Device Viewport Tests
chromium Desktop Chrome 1280Γ—720 All tests (46)
mobile Pixel 5 393Γ—851 Excluding @desktop-only (41)

Tests tagged with @desktop-only are skipped on mobile because they test features not visible on mobile (e.g., header navigation links).

Test Structure

tests/
β”œβ”€β”€ e2e/
β”‚   β”œβ”€β”€ features/           # Gherkin feature files
β”‚   β”‚   β”œβ”€β”€ homepage.feature
β”‚   β”‚   β”œβ”€β”€ navigation.feature
β”‚   β”‚   β”œβ”€β”€ search.feature
β”‚   β”‚   β”œβ”€β”€ search-results.feature
β”‚   β”‚   β”œβ”€β”€ article.feature
β”‚   β”‚   β”œβ”€β”€ topics.feature
β”‚   β”‚   β”œβ”€β”€ sources.feature
β”‚   β”‚   β”œβ”€β”€ language-switching.feature
β”‚   β”‚   └── theme-toggle.feature
β”‚   β”œβ”€β”€ steps/              # Step definitions
β”‚   β”‚   β”œβ”€β”€ common.steps.ts
β”‚   β”‚   β”œβ”€β”€ homepage.steps.ts
β”‚   β”‚   β”œβ”€β”€ navigation.steps.ts
β”‚   β”‚   β”œβ”€β”€ search.steps.ts
β”‚   β”‚   β”œβ”€β”€ search-results.steps.ts
β”‚   β”‚   β”œβ”€β”€ article.steps.ts
β”‚   β”‚   β”œβ”€β”€ topics.steps.ts
β”‚   β”‚   β”œβ”€β”€ sources.steps.ts
β”‚   β”‚   β”œβ”€β”€ language.steps.ts
β”‚   β”‚   └── theme.steps.ts
β”‚   └── fixtures/           # Page objects
β”‚       └── pages.ts
β”œβ”€β”€ unit/
β”‚   β”œβ”€β”€ lib/
β”‚   β”‚   β”œβ”€β”€ content.test.ts
β”‚   β”‚   └── search.test.ts
β”‚   └── setup.ts
β”œβ”€β”€ playwright.config.ts
└── vitest.config.ts

Writing E2E Tests

E2E tests use Gherkin syntax for human-readable scenarios:

Feature: Search
  As a user I want to search for Bitcoin articles

  Scenario: Hero search shows results
    Given I am on the homepage
    When I type "bitcoin" in the hero search field
    Then I see search results in the dropdown
    And the first result contains "Bitcoin"

Test Tags

Use tags to control which tests run on which devices:

# This test only runs on Desktop (chromium)
@desktop-only
Scenario: Header navigation is visible
  Then I see the navigation links

# This test runs on both Desktop and Mobile
Scenario: Logo leads to homepage
  When I click on the logo
  Then I should be on the homepage
Tag Description
@desktop-only Skipped on mobile - tests desktop-specific features

Data-TestIDs

All interactive components have data-testid attributes for reliable test selectors:

Component Test IDs
Hero Section hero-title, hero-search-input, hero-search-dropdown, hero-search-result-{index}
Search Modal search-modal, search-modal-input, search-modal-close, search-result-{index}
Header header, header-logo, header-search-button, header-nav-topics, theme-toggle, language-toggle
Article article-title, article-content, article-toc, article-back-button
Topics topics-grid, topic-card-{id}, topic-title, topic-articles
Sources sources-page, sources-grid, sources-filters, sources-filter-{type}
Search Page search-page, search-page-input, search-results, search-page-result-{index}

CI/CD

Tests run automatically on every push and pull request via GitHub Actions:

  1. Lint & Type Check - ESLint and TypeScript validation
  2. Unit Tests - Vitest unit test suite
  3. E2E Tests - Playwright browser tests
  4. Build - Production build verification

πŸ“ˆ Next Steps (Not Implemented Yet)

PostHog Analytics

Add to src/app/layout.tsx:

import posthog from 'posthog-js';

if (typeof window !== 'undefined') {
  posthog.init('YOUR_POSTHOG_KEY', {
    api_host: 'https://app.posthog.com',
  });
}

Supabase Backend

  1. Install Supabase client: pnpm add @supabase/supabase-js
  2. Create src/lib/supabase/client.ts
  3. Add environment variables
  4. Implement auth, user progress tracking, etc.

Multi-language Support

The content structure already supports multiple languages:

  • Add content/de/ for German
  • Update content loader to accept language parameter
  • Implement language switcher component

Mobile App

Consider using Capacitor or React Native to wrap the web app for mobile distribution.

🀝 Contributing

Contributions are welcome! Please read the contributing guidelines first.

πŸ“„ License

MIT License - see LICENSE file for details.


Built with ❀️ for the Bitcoin community.

About

Mobile-first Bitcoin & sound-money knowledge base with analytics and experimentation via PostHog.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published