A comprehensive Bitcoin narrative intelligence platform built with React, Cloudflare infrastructure, and Ghost CMS.
- Production: https://perception.to
- Newsletter/Research: https://perception.to/bitcoin-media-research
- Sentiment Index: https://perception.to/bitcoin-market-sentiment
- Conference Tracker: https://perception.to/crypto-conferences
┌─────────────────────────────────────────────────────────────────────────────┐
│ perception.to │
│ (Cloudflare Pages) │
├─────────────────────────────────────────────────────────────────────────────┤
│ Frontend (React + Vite) │ Functions (Workers) │ Content (Ghost CMS) │
│ - TypeScript │ - SEO Middleware │ - Newsletter Posts │
│ - Tailwind CSS │ - OG Image Gen │ - Research Articles │
│ - React Router │ - Bot Detection │ - Build-time Fetch │
└─────────────────────────────────────────────────────────────────────────────┘
│
┌───────────────────────┼───────────────────────┐
│ │ │
▼ ▼ ▼
Ghost CMS API Firebase/GCP APIs MongoDB Atlas
(Content) (Sentiment, Trends) (Learn, Glossary)
| Layer | Technology |
|---|---|
| Frontend | React 18, TypeScript, Vite, Tailwind CSS |
| Hosting | Cloudflare Pages |
| Functions | Cloudflare Workers (Edge Functions) |
| CMS | Ghost Pro (Newsletter & Research) |
| Database | MongoDB Atlas (Learn/Glossary), Firestore (App Data) |
| APIs | Firebase Functions, Google Cloud Run |
| Auth | Firebase Authentication |
- Node.js 20+
- npm or yarn
- Ghost Content API Key (for full builds)
# Clone repository
git clone https://github.com/fernikolic/perception-to.git
cd bitcoin-perception
# Install dependencies
npm install
# Start development server
npm run devCreate .env.local:
# Ghost CMS (required for full builds)
GHOST_API_URL=https://bitcoin-perception.ghost.io
GHOST_CONTENT_API_KEY=your_content_api_key# Full production build
npm run build
# Deploy to Cloudflare Pages
npx wrangler pages deploy dist --project-name=perception-tobitcoin-perception/
├── src/ # React frontend
│ ├── pages/
│ │ ├── bitcoin-media-research/ # Newsletter & Research pages
│ │ ├── bitcoin-market-sentiment/ # Sentiment pages
│ │ ├── crypto-conferences/ # Conference tracker
│ │ └── learn/ # Educational content
│ ├── components/ # Reusable components
│ ├── lib/
│ │ └── ghost.ts # Ghost CMS client
│ └── data/
│ └── ghost-posts.json # Cached Ghost content
├── functions/ # Cloudflare Workers
│ ├── _middleware.js # SEO middleware
│ ├── seo-config.js # Page SEO configs
│ └── api/ # API endpoints
├── scripts/ # Build scripts
│ ├── fetch-ghost-posts.js # Ghost content fetcher
│ └── generate-*.js # Sitemap generators
├── docs/ # Documentation
│ ├── infrastructure/ # Infrastructure docs
│ ├── api/ # API documentation
│ └── ... # Feature documentation
└── public/ # Static assets
- Ghost CMS powered content
- Newsletter signup integration
- Research reports and opinion articles
- Build-time content fetching
- Daily/monthly sentiment tracking
- Historical data visualization
- Fear & Greed Index
- Bitcoin/crypto conference directory
- Real-time updates via Firestore
- Automatic sitemap generation
- Cloudflare Workers middleware for bot detection
- Dynamic meta tag injection
- Structured data (JSON-LD)
- Dynamic OG image generation
| Script | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Full production build |
npm run ghost:fetch |
Fetch Ghost CMS content |
npm run sitemap:all |
Generate all sitemaps |
npm run social:generate |
Generate social image config |
- Infrastructure Overview - Complete infrastructure docs
- API Reference - Backend API documentation
- Project Overview - Development guide
Content is fetched from Ghost at build time:
- Fetch:
npm run ghost:fetchpulls posts from Ghost API - Cache: Posts saved to
src/data/ghost-posts.json - Build: React components read from cached JSON
- Deploy: Static content served from Cloudflare edge
| Type | Tag | URL |
|---|---|---|
| All Posts | - | /bitcoin-media-research |
| Reports | reports |
/bitcoin-media-research/reports |
| Opinion | opinion |
/bitcoin-media-research/opinion |
- Production Branch:
main - Build Command:
npm run build - Build Output:
dist - Node.js Version: 20
Set in Cloudflare Dashboard > Pages > Settings > Environment Variables:
| Variable | Environment |
|---|---|
GHOST_CONTENT_API_KEY |
Production & Preview |
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
Proprietary - All rights reserved.
Built with care for the Bitcoin community.