A production-grade, SEO-optimized content platform delivering expert battery guides, interactive diagnostic tools, and practical tips across phone, laptop, and solar battery categories. Built as a full-stack Next.js application with a headless CMS admin panel, Supabase backend, and automated content pipeline.
Live: bestbatteryguides.com
- Project Overview
- Tech Stack
- Architecture
- Features
- Content Pipeline
- SEO Pipeline
- Admin CMS
- Interactive Tools
- Project Structure
- Scripts and Automation
- Deployment
- Environment Variables
- Getting Started
Battery Guides is a content-first web application targeting users searching for battery troubleshooting, maintenance, and buying advice. The platform combines long-form MDX editorial content with interactive client-side tools, structured data for search engines, and a custom admin dashboard for content management -- all within a single Next.js monorepo.
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router, React Server Components) |
| Language | TypeScript 5 |
| UI Library | React 19 |
| Styling | Tailwind CSS 4 (PostCSS plugin) |
| Typography | @tailwindcss/typography |
| Animations | Framer Motion |
| Icons | Lucide React |
| Rich Text Editor | TipTap (admin CMS) |
| Search (client) | Fuse.js (fuzzy search over pre-built index) |
| Notifications | Sonner (toast system) |
| Layer | Technology |
|---|---|
| Runtime | Node.js (Next.js API Routes) |
| Database / BaaS | Supabase (PostgreSQL, Storage, Auth) |
| Authentication | Custom HMAC-SHA256 session tokens (HttpOnly cookies, Web Crypto API) |
| Content Format | MDX (static files) + Supabase posts (dynamic CMS) |
| Markdown Parsing | gray-matter, next-mdx-remote, remark-gfm |
| HTML-to-MDX | Turndown + turndown-plugin-gfm |
| Layer | Technology |
|---|---|
| Metadata | Next.js Metadata API (per-page canonical, Open Graph, Twitter Cards) |
| Structured Data | JSON-LD (Organization, WebSite, Article, FAQ, BreadcrumbList, WebApplication) |
| Sitemap | next-sitemap (dynamic paths from Supabase at build time) |
| Robots.txt | Auto-generated via next-sitemap |
| Analytics | Google Analytics 4, Vercel Analytics |
| Monetization | Google AdSense (dynamic ad injection with spacing overlay for dev) |
| Layer | Technology |
|---|---|
| Package Manager | pnpm (workspace enabled) |
| Linting | ESLint 9 (flat config), eslint-config-next |
| Build | Next.js compiler (Turbopack-compatible) |
| Image Optimization | Next.js Image (AVIF/WebP, responsive srcset, blur placeholders) |
| Security Headers | X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, Referrer-Policy |
| Version Control | Git |
| Hosting | Vercel |
Client (Browser)
|
v
Next.js App Router (SSR / SSG / ISR)
|
+--- Static MDX Content (src/content/**/*.mdx)
| parsed at build time via gray-matter + next-mdx-remote
|
+--- Dynamic CMS Content (Supabase PostgreSQL)
| fetched at request time via @supabase/supabase-js
| rendered through TipTap HTML -> React pipeline
|
+--- API Routes (/api/admin/*, /api/subscribe, /api/navigation)
| HMAC-SHA256 session auth, CRUD for posts/media/settings
|
+--- Client-Side Tools (React interactive calculators)
| state managed locally, no backend calls
|
+--- Search Index (pre-built JSON, Fuse.js client-side)
|
v
Supabase
+--- PostgreSQL (posts, media, settings, subscribers)
+--- Storage (image uploads)
+--- Service Role Key (admin operations)
+--- Anon Key (public read)
- Hybrid content system: static MDX files for core articles, Supabase-backed CMS for dynamic posts
- 4 content categories: Phone, Laptop, Solar, General Questions
- 29+ published articles across all categories
- Related articles engine with frontmatter-based and category-based fallback matching
- Internal link suggestion system using keyword overlap scoring
- Article layouts with table of contents, FAQ sections, author bios, share buttons, and sidebar popular posts
- Ad injection system that splits MDX content and inserts ad units at configurable intervals
- Responsive mega-menu navbar with categorized dropdown clusters
- Full-text client-side search with modal UI and fuzzy matching
- Breadcrumb navigation with JSON-LD structured data
- Navigation progress bar (NProgress-style)
- Scroll-to-top button
- Skip-to-content link for accessibility
- Page transition animations
- Loading states with skeleton UI
- Custom 404 page
- React Server Components for zero-JS article rendering
- Next.js Image optimization with AVIF/WebP format negotiation
- Responsive image srcset with custom device and image size breakpoints
- Blur placeholder generation for images
- 30-day minimum image cache TTL
- Pre-built search index (generated at build time, not runtime)
Author writes MDX
|
v
src/content/{category}/{slug}.mdx
| (frontmatter: title, excerpt, slug, category, author,
| publishedAt, updatedAt, featuredImage, relatedArticles, faqs)
|
v
Build Step: generate-search-index.mjs
| -> reads all MDX frontmatter + tool definitions
| -> outputs src/data/search-index.json
|
v
Build Step: next-sitemap
| -> queries Supabase for published posts
| -> generates sitemap.xml with per-route priority and changefreq
| -> generates robots.txt
|
v
Build Step: validate-article-internal-links.mjs
| -> checks all internal links across articles resolve
|
v
Build Step: count-mdx-words.mjs
| -> reports word counts per article for editorial quality control
|
v
Deployment (Vercel)
-> SSR/SSG pages with full metadata, JSON-LD, Open Graph
Admin logs in (/admin/login)
| HMAC-SHA256 session cookie (24h TTL, Web Crypto API)
|
v
TipTap Rich Text Editor
| extensions: code blocks (lowlight), images, tables,
| links, colors, highlights, YouTube embeds, task lists,
| text alignment, underline
|
v
Save to Supabase (PostgreSQL)
| fields: title, slug, category, subcategory, excerpt,
| body_html, featured_image, status, meta_title, meta_description,
| faqs, related_articles, internal_links
|
v
Media uploads -> Supabase Storage
|
v
Public site fetches published posts at request time
-> renders HTML content with embedded tool blocks, FAQ sections,
comparison tables, and interactive components
Every page generates structured metadata through a centralized builder system:
- Article pages: Open Graph article type, canonical URLs, publish/modified dates, featured images, author attribution
- Tool pages: WebApplication JSON-LD with free pricing, application category, browser requirements
- Category listings: Dedicated metadata with indexed/followed robots directives
- Legal pages: nofollow robots directive, minimal priority in sitemap
- Homepage: Organization + WebSite JSON-LD, SearchAction for sitelinks search box
Sitemap generation queries Supabase at build time with priority tiers:
- Homepage: 1.0 (daily)
- Category pages: 0.9 (weekly)
- Articles: 0.8 (monthly)
- Tools: 0.75 (monthly)
- Legal: 0.3 (yearly)
Custom-built headless CMS accessible at /admin:
- Session-based authentication with HMAC-SHA256 signed tokens
- Post management: create, edit, preview, publish/draft/archive workflow
- TipTap rich text editor with 15+ extensions (code blocks with syntax highlighting, tables, images, YouTube embeds, task lists, text formatting)
- Media library with Supabase Storage integration
- HTML-to-MDX conversion pipeline (Turndown)
- Site settings management
- Category and subcategory organization
- Slug auto-generation with validation
Six client-side battery tools built as React components:
| Tool | Description |
|---|---|
| Charging Time Calculator | Estimates charge time based on battery capacity, charger wattage, device type, and efficiency loss |
| Solar Battery Sizer | Calculates battery bank size for solar systems based on daily energy usage |
| Laptop Runtime Estimator | Projects remaining runtime from battery specs and power draw |
| Battery Cycle Calculator | Estimates cycle life and replacement timeline |
| Battery Health Checklist | Interactive diagnostic checklist with scoring |
| Phone Diagnostic Flow | Step-by-step troubleshooting decision tree |
Each tool generates WebApplication JSON-LD for rich search results.
battery-guides/
|-- src/
| |-- app/
| | |-- (site)/ # Public routes (grouped layout)
| | | |-- page.tsx # Homepage
| | | |-- phone/ # Phone category + [slug] articles
| | | |-- laptop/ # Laptop category + [slug] articles
| | | |-- solar/ # Solar category + [slug] articles
| | | |-- general-questions/ # General category + [slug] articles
| | | |-- battery-tools/ # Interactive tools hub + individual tools
| | | |-- search/ # Search results page
| | | |-- about/ # About page
| | | |-- contact/ # Contact page
| | | |-- subscribe/ # Newsletter subscription
| | | |-- privacy-policy/ # Legal pages
| | | |-- terms/
| | | |-- disclaimer/
| | | |-- not-found.tsx
| | | |-- layout.tsx # Site shell (navbar, footer, analytics)
| | | |-- template.tsx # Page transition wrapper
| | | +-- loading.tsx # Loading skeleton
| | |-- admin/ # Admin CMS dashboard
| | | |-- login/
| | | |-- posts/ # Post list, editor, preview
| | | |-- media/ # Media library
| | | |-- settings/
| | | +-- layout.tsx # Admin shell
| | +-- api/ # API routes
| | |-- admin/ # Auth, posts CRUD, media, settings
| | |-- subscribe/ # Newsletter subscription endpoint
| | +-- navigation/ # Dynamic nav data
| |-- components/
| | |-- admin/ # CMS editor, toolbar, sidebar
| | |-- analytics/ # Google Analytics loader
| | |-- article/ # Article layout, TOC, FAQ, MDX renderer
| | |-- category/ # Category listing cards and grids
| | |-- comparison/ # Product comparison tables
| | |-- dev/ # Development overlays (ad spacing)
| | |-- home/ # Homepage sections (hero, stats, CTA)
| | |-- layout/ # Navbar, footer, sidebar, ads, a11y
| | |-- legal/ # Legal page layout, contact form
| | |-- mdx/ # Custom MDX components
| | |-- seo/ # JSON-LD structured data components
| | |-- shared/ # Newsletter CTA, share buttons
| | |-- tools/ # Interactive calculator components
| | +-- ui/ # Search modal, breadcrumbs, animations
| |-- content/ # Static MDX articles
| | |-- phone/ # 10 articles
| | |-- laptop/ # 6 articles
| | |-- solar/ # 6 articles
| | +-- general-questions/ # 9 articles
| |-- data/ # Static data (site config, tools, search index)
| |-- hooks/ # Custom React hooks
| |-- lib/ # Utilities
| | |-- seo/ # Metadata builders, URL helpers
| | |-- supabase.ts # Client initialization (public + admin)
| | |-- mdx.ts # MDX parsing, article queries
| | |-- admin-session.ts # HMAC-SHA256 session management
| | |-- internal-links.ts # Cross-article link suggestions
| | +-- search.ts # Search utilities
| |-- types/ # TypeScript type definitions
| +-- constants/ # Ad configuration
|-- scripts/ # Build-time automation
| |-- generate-search-index.mjs
| |-- validate-article-internal-links.mjs
| |-- count-mdx-words.mjs
| |-- replace-unsplash-urls.mjs
| +-- lighthouse-hint.mjs
|-- public/ # Static assets
|-- next.config.ts # Next.js configuration
|-- next-sitemap.config.js # Sitemap generation config
|-- tsconfig.json
|-- eslint.config.mjs
|-- postcss.config.mjs
+-- pnpm-workspace.yaml
| Command | Description |
|---|---|
pnpm dev |
Start development server |
pnpm build |
Run search index generation, build Next.js, generate sitemap |
pnpm start |
Start production server |
pnpm lint |
Run ESLint |
pnpm check:internal-links |
Validate all internal article links resolve |
pnpm check:word-counts |
Report word counts per MDX article |
pnpm qa |
Full QA pipeline: build + link check + word counts |
pnpm lighthouse |
Lighthouse audit hints |
Build pipeline order:
prebuild-- generatessrc/data/search-index.jsonfrom MDX frontmatterbuild-- Next.js compilation (SSR/SSG)postbuild-- generatessitemap.xmlandrobots.txtvia next-sitemap
The application is deployed on Vercel with the following configuration:
- Automatic deployments on push to main branch
- Environment variables configured in Vercel dashboard
- Image optimization handled by Vercel edge network
- AVIF/WebP format negotiation
- Security headers applied via
next.config.ts - Supabase connection for dynamic content and media storage
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Supabase project URL (public) |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Supabase anonymous key (public reads) |
SUPABASE_SERVICE_ROLE_KEY |
Supabase service role key (admin operations) |
ADMIN_PASSWORD |
Admin login password |
ADMIN_SESSION_SECRET |
HMAC signing secret for session tokens |
NEXT_PUBLIC_SITE_URL |
Canonical site URL |
NEXT_PUBLIC_GA_ID |
Google Analytics 4 measurement ID |
NEXT_PUBLIC_ADSENSE_CLIENT |
Google AdSense publisher ID |
# Clone the repository
git clone https://github.com/BlackAlpha-debug/Battery-Guides.git
cd Battery-Guides
# Install dependencies
pnpm install
# Set up environment variables
cp .env.example .env.local
# Fill in Supabase credentials and other values
# Run development server
pnpm dev
# Full QA pipeline
pnpm qa